From: Jarmo Pertman Date: 2010-09-01T22:13:25+09:00 Subject: Re: rsa sign and verify with openssl on windows Thank you for these great answers, Brian! In Java the name of the algorithm was "SHA1withRSA" and i tried to do it - RSA(SHA1). Unfortunately i totally forgout about the padding issue and Ruby OpenSSL documentation is just not there. I still couldn't find a documentation for this #sign method and that's why i didn't use it. As soon as i started using the #sign method with OpenSSL::Digest::SHA1 everything started to work :) So, if someone is struggling with the same problem then don't try to use Digest::SHA1 and #private_encrypt directly, but use #sign instead like this: private_key.sign(OpenSSL::Digest::SHA1.new, "data") I wish that the documentation for some stdlibs would be better. Thank You again, Brian! Jarmo Brian Candler wrote: > Here are some tests on ubuntu Lucid with ruby 1.8.7 > > $ openssl genrsa -out priv.pem 1024 > Generating RSA private key, 1024 bit long modulus > ....++++++ > ...................++++++ > e is 65537 (0x10001) > > $ openssl rsa -in priv.pem -out pub.pem -pubout > writing RSA key > > $ irb --simple-prompt >>> require 'openssl' > => true >>> private_key = OpenSSL::PKey::RSA.new(File.read('priv.pem')); nil > => nil >>> File.open("pub2.pem","w") { |f| f.write private_key.public_key } > => 251 > > $ cat pub.pem > -----BEGIN PUBLIC KEY----- > MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCx5oz9tweJf4OZaM3y/0JRUeS3 > Ctyy7zuPmrf2D/EK6GO4a+8OIG/Q++XskSIrqFUXAMjVDfM4zrGAwdzVRaKBo5an > 2YskZFfT5YizOxyzyxjQ7+Z7kgNH7O7KEXCXOdSa8Bg3qQp40ChVI4kpdWTYlmS5 > YY7lWqRLTAYYdVkVAQIDAQAB > -----END PUBLIC KEY----- > > brian@zino:~$ cat pub2.pem > -----BEGIN RSA PUBLIC KEY----- > MIGJAoGBALHmjP23B4l/g5lozfL/QlFR5LcK3LLvO4+at/YP8QroY7hr7w4gb9D7 > 5eyRIiuoVRcAyNUN8zjOsYDB3NVFooGjlqfZiyRkV9PliLM7HLPLGNDv5nuSA0fs > 7soRcJc51JrwGDepCnjQKFUjiSl1ZNiWZLlhjuVapEtMBhh1WRUBAgMBAAE= > -----END RSA PUBLIC KEY----- > > Now, I see that openssl is happy with pub.pem: > > $ openssl rsa -in pub.pem -pubin -noout -text > > but fails to read pub2.pem (even if you change "RSA PUBLIC KEY" to > "PUBLIC KEY") > $ openssl rsa -in pub2.pem -pubin -noout -text > > Ruby can read it back though (although interestingly, ruby 1.8.6 under > Ubuntu Hardy cannot) > >>> public_key = OpenSSL::PKey::RSA.new(File.read("pub2.pem")) > => -----BEGIN RSA PUBLIC KEY----- > MIGJAoGBALHmjP23B4l/g5lozfL/QlFR5LcK3LLvO4+at/YP8QroY7hr7w4gb9D7 > 5eyRIiuoVRcAyNUN8zjOsYDB3NVFooGjlqfZiyRkV9PliLM7HLPLGNDv5nuSA0fs > 7soRcJc51JrwGDepCnjQKFUjiSl1ZNiWZLlhjuVapEtMBhh1WRUBAgMBAAE= > -----END RSA PUBLIC KEY----- > > But I think this is probably a side-issue of outputting public keys. > > The real question is, what algorithm are you trying to implement in > ruby? Are you trying to do something along the lines of "openssl rsautl > -sign" ? In that case, you should use the OpenSSL API for that, as it > deals with all the padding correctly. > >>> pk = OpenSSL::PKey::RSA.new(File.read("priv.pem")) > ... >>> File.open("enc1.dat","wb") { |f| f.write pk.sign("sha1", "hello world") } > => 128 > > This file is quite happily read by openssl command line: > > $ openssl rsautl -in enc1.dat -verify -inkey priv.pem -raw -hexdump > 0000 - 00 01 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff > ................ > 0010 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff > ................ > 0020 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff > ................ > 0030 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff > ................ > 0040 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff > ................ > 0050 - ff ff ff ff ff ff ff ff-ff ff ff ff 00 30 21 30 > .............0!0 > 0060 - 09 06 05 2b 0e 03 02 1a-05 00 04 14 2a ae 6c 35 > ...+........*.l5 > 0070 - c9 4f cf b4 15 db e9 5f-40 8b 9c e9 1e e8 46 ed > .O....._@.....F. > > And you can see that it includes the expected digest in the last 20 > bytes: > > $ echo -n "hello world" | openssl dgst -sha1 -hex > 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed -- Posted via http://www.ruby-forum.com/.