# RSA public\_encrypt bug?

**URL:** <https://www.ruby-forum.com/t/rsa-public-encrypt-bug/151153>\
**Category:** Ruby\
**Created:** [October 17, 2008, 12:57pm UTC](https://www.ruby-forum.com/t/rsa-public-encrypt-bug/151153 "2008-10-17T12:57:24Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![dani](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/35a633/32.png) [@dani](https://www.ruby-forum.com/u/dani)\
**Post date:** [October 17, 2008, 12:57pm UTC](https://www.ruby-forum.com/t/rsa-public-encrypt-bug/151153/1 "2008-10-17T12:57:24Z")

</div>

Hi, I’m trying to encrypt some data with an RSA public key, this is  
the code which is failing:

* * *

require ‘openssl’

f=File.open(‘public\_key.txt’)  
rsa = OpenSSL::PKey::RSA  
rsa.n = OpenSSL::BN.new f.gets  
rsa.e = OpenSSL::BN.new f.gets

## encrypted\_data = rsa.public\_encrypt(‘Hi’) puts "Size: " + encrypted\_data.size.to\_s

In Windows, using ruby-1.8.6, I says that the size of the encrypted  
data is 51 bytes, where in reality the encrypted data should be 64  
bytes.  
In Linux, using ruby-1.8.5, the same code just gives an error:

$ ruby test.rb  
test.rb:9:in `public\_encrypt’: no inverse (OpenSSL::PKey::RSAError)  
from test.rb:9

I’m stunned… I’ve even checked ossl\_pkey\_rsa.c and I haven’t seen  
anything wrong. Any help appreciated.

---

<div class="post-metadata">

**Author:** ![dani](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/35a633/32.png) [@dani](https://www.ruby-forum.com/u/dani)\
**Post date:** [October 17, 2008, 5:21pm UTC](https://www.ruby-forum.com/t/rsa-public-encrypt-bug/151153/2 "2008-10-17T17:21:20Z")

</div>

Dani P. wrote:

> Hi, I’m trying to encrypt some data with an RSA public key, this is  
> the code which is failing:

Your life might be easier if you read your public key from a PEM file  
🙂

I don’t know why your code doesn’t work. However I have attached some  
code I wrote about 4 years ago which I used to construct a key from its  
parameters (before writing it out as a PEM). It seems you’re doing the  
right things, but maybe the comments are relevant.

I think I was using integers, so perhaps f.gets.to\_i ?

Also, you could try writing out a PEM, and then using that at the  
openssl command line, to check that your key is actually valid.

---

<div class="post-metadata">

**Author:** ![dani](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/35a633/32.png) [@dani](https://www.ruby-forum.com/u/dani)\
**Post date:** [October 17, 2008, 5:32pm UTC](https://www.ruby-forum.com/t/rsa-public-encrypt-bug/151153/3 "2008-10-17T17:32:31Z")

</div>

Brian C. wrote:

> I think I was using integers, so perhaps f.gets.to\_i ?
> 
> Also, you could try writing out a PEM, and then using that at the  
> openssl command line, to check that your key is actually valid.

Here’s the rest of the code which I used (in 2004 🙂 to do this for a  
private key - however I think if you just remove the p and q bits then  
you should get a public key instead.

require ‘openssl’  
require ‘rsa\_new’

# Input: a large number n

# an exponent

# factor p of n

# factor q of n (n = p \* q)

# Output: a PEM-encoded private key

n = gets.to\_i  
e = gets.to\_i  
p = gets.to\_i  
q = gets.to\_i  
p,q = q,p if p \< q

puts OpenSSL::PKey::RSA.new\_from\_parameters(n, e, nil, p, q)

---

<div class="post-metadata">

**Author:** ![dani](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/35a633/32.png) [@dani](https://www.ruby-forum.com/u/dani)\
**Post date:** [October 17, 2008, 5:42pm UTC](https://www.ruby-forum.com/t/rsa-public-encrypt-bug/151153/4 "2008-10-17T17:42:21Z")

</div>

On Fri, Oct 17, 2008 at 5:20 PM, Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Dani P. wrote:
> 
> > Hi, I’m trying to encrypt some data with an RSA public key, this is  
> > the code which is failing:
> 
> Your life might be easier if you read your public key from a PEM file  
> 🙂

Yeah, but as you can figure out I don’t have it. I have a file with  
two lines, the module and the exponent.

> I don’t know why your code doesn’t work. However I have attached some  
> code I wrote about 4 years ago which I used to construct a key from its  
> parameters (before writing it out as a PEM). It seems you’re doing the  
> right things, but maybe the comments are relevant.
> 
> I think I was using integers, so perhaps f.gets.to\_i ?  
> Also, you could try writing out a PEM, and then using that at the  
> openssl command line, to check that your key is actually valid.

Actually, what I’ve found out is that after populating the modulus  
and exponent, if I print the key:

–  
rsa.n = OpenSSL::BN.new f.gets  
rsa.e = OpenSSL::BN.new f.gets

## puts rsa.to\_text

The modulus that #to\_text reports doesn’t ressemble what I have on  
the public key I’ve got on a text file… :?  
Also, the modulus reported by #to\_text is 51 bytes (?), while the  
public modulus I’ve got in the text file is 128 characters in hex,  
which is 64 bytes.  
My cryptographic skills are not very good, but any hint appreciated 🙂

---

<div class="post-metadata">

**Author:** ![dani](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/35a633/32.png) [@dani](https://www.ruby-forum.com/u/dani)\
**Post date:** [October 17, 2008, 6:20pm UTC](https://www.ruby-forum.com/t/rsa-public-encrypt-bug/151153/5 "2008-10-17T18:20:28Z")

</div>

On Fri, Oct 17, 2008 at 6:04 PM, Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> So try changing your code to:
> 
> rsa.n = OpenSSL::BN.new(f.gets.to\_i(16).to\_s)

Woops, you’re true, that was the problem!. I thought OpenSSL::BN  
would read hex. It reads an string that should be on base10. Strange  
though that it wasn’t raising an exception.

Thanks!

---

<div class="post-metadata">

**Author:** ![dani](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/35a633/32.png) [@dani](https://www.ruby-forum.com/u/dani)\
**Post date:** [October 17, 2008, 6:05pm UTC](https://www.ruby-forum.com/t/rsa-public-encrypt-bug/151153/6 "2008-10-17T18:05:37Z")

</div>

Dani P. wrote:

> Actually, what I’ve found out is that after populating the modulus  
> and exponent, if I print the key:
> 
> –  
> rsa.n = OpenSSL::BN.new f.gets  
> rsa.e = OpenSSL::BN.new f.gets
> 
> ## puts rsa.to\_text
> 
> The modulus that #to\_text reports doesn’t ressemble what I have on  
> the public key I’ve got on a text file… :?

You want to post your n and e here? They are a _public_ key, after all  
🙂

> Also, the modulus reported by #to\_text is 51 bytes (?), while the  
> public modulus I’ve got in the text file is 128 characters in hex,  
> which is 64 bytes.

Aha! OpenSSL::BN reads decimal, not hex! Remember that irb is your  
friend:

irb(main):001:0\> require ‘openssl’  
=\> true  
irb(main):002:0\> x = OpenSSL::BN.new(“1234”)  
=\> 1234  
irb(main):003:0\> x = OpenSSL::BN.new(“12AB”)  
=\> 12

So try changing your code to:

rsa.n = OpenSSL::BN.new(f.gets.to\_i(16).to\_s)

Or more simply, you should just be able to write:

rsa.n = f.gets.to\_i(16)
