# Ruby openssl ECC help plz

**URL:** <https://rubytalk.org/t/ruby-openssl-ecc-help-plz/65162>\
**Category:** ruby-talk\
**Created:** [31 March 2012 00:16 UTC](https://rubytalk.org/t/ruby-openssl-ecc-help-plz/65162 "2012-03-31T00:16:09Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [31 March 2012 00:16 UTC](https://rubytalk.org/t/ruby-openssl-ecc-help-plz/65162/1 "2012-03-31T00:16:09Z")

</div>

I am confused on how to properly export public ECC key. I can see it  
only if I export both public key and private key with to\_text, which is  
bad. Otherwise how do I export just the public key? I have two ideas :

require "openssl"

puts OpenSSL::PKey::EC.builtin\_curves  
cipher = OpenSSL::Cipher::Cipher.new("AES-256-OFB")

key = OpenSSL::PKey::EC.new("prime192v1")  
key.generate\_key  
puts key.to\_pem(cipher, "testing")

#my first guess, and what I still think seems most likely to be correct  
a = key.public\_key  
puts a.to\_bn

#however this produces a 936 bit number and I think my public key should  
be #much smaller than this...is converting it to a big number changing  
the #bit size and confusing me ?

#Pretty sure this is wrong...

puts key.dh\_compute\_key(a).bytesize

#Because I think this generates a ECDH shared secret using the public  
key #of someone else (if they ever manage to export it....). But I have  
my own #questions about this. Why does it take only one parameter? Ok  
the #elliptic curve is already specified with key, and then their public  
key, #but how do I specify my private key? Also this makes a shared  
secret (I #think that is what it is doing) that is under 256 bits but  
with my #elliptic curve set at what it is I would think the shared  
secret would be #slightly over 256 bits.....

also any help to clarify ruby openssl ecc is appreciated the  
documentation is extremely lacking and I start to get it figured out but  
it is much harder than the using ruby RSA or any of the symmetric  
algorithms, and also much less documented (these things are related)

thanks!

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Martin\_Bosslet1](https://avatars.discourse-cdn.com/v4/letter/m/90db22/32.png) [@Martin\_Bosslet1](https://rubytalk.org/u/Martin_Bosslet1)\
**Post date:** [31 March 2012 01:48 UTC](https://rubytalk.org/t/ruby-openssl-ecc-help-plz/65162/2 "2012-03-31T01:48:08Z")

</div>

> I am confused on how to properly export public ECC key. I can see it  
> only if I export both public key and private key with to\_text, which is  
> bad. Otherwise how do I export just the public key?

It's a bit tricky in the sense that you need to create a second EC instance  
which will only be assigned the public key. Unfortunately you can't to the  
straightforward thing ec.public\_key.to\_der, but you can do it like this:

key = OpenSSL::PKey::EC.new  
key.group = OpenSSL::PKey::EC::Group.new('prime256v1')  
key.generate\_key

pub = OpenSSL::PKey::EC.new(key.group)  
pub.public\_key = key.public\_key  
pem = pub.to\_pem # to\_der is possible, too, of course

gives you the public key encoding:

-----BEGIN PUBLIC KEY-----  
MFkw...  
-----END PUBLIC KEY-----

> #however this produces a 936 bit number and I think my public key should  
> be #much smaller than this...is converting it to a big number changing  
> the #bit size and confusing me ?
> 
> #Pretty sure this is wrong...
> 
> puts key.dh\_compute\_key(a).bytesize
> 
> #Because I think this generates a ECDH shared secret using the public  
> key #of someone else (if they ever manage to export it....). But I have  
> my own #questions about this. Why does it take only one parameter? Ok  
> the #elliptic curve is already specified with key, and then their public  
> key, #but how do I specify my private key?

You don't have to - you are calling #dh\_compute\_key on an instance of EC,  
which consists of both the public key (point) and the private key (integer),  
and the parameter you pass in is the peer's public key (point).

> Also this makes a shared  
> secret (I #think that is what it is doing) that is under 256 bits but  
> with my #elliptic curve set at what it is I would think the shared  
> secret would be #slightly over 256 bits.....

Hmm, the result should always be of the same size, it depends on the  
actual curve what its output size finally will be. Which curve are you using?

> also any help to clarify ruby openssl ecc is appreciated the  
> documentation is extremely lacking and I start to get it figured out but  
> it is much harder than the using ruby RSA or any of the symmetric  
> algorithms, and also much less documented (these things are related)

Yes, I am aware of that, when I have the time, we'll add more docs!

> **···**
>
> Am 31. März 2012 02:16 schrieb no name \<lists@ruby-forum.com\>:

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [31 March 2012 10:04 UTC](https://rubytalk.org/t/ruby-openssl-ecc-help-plz/65162/3 "2012-03-31T10:04:48Z")

</div>

Thanks I have it working now. I have one other question, why doesn't  
ruby openssl support counter mode of operation??

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [1 April 2012 00:57 UTC](https://rubytalk.org/t/ruby-openssl-ecc-help-plz/65162/4 "2012-04-01T00:57:51Z")

</div>

thanks for the help. I am having a hellish time getting ruby to  
recognize the updated openSSL. First I compile new one from source,  
since it is not in the repository of my OS. After I compile the new  
version OpenSSL still thinks it is (and therefor is...) the old version  
that came with my OS. So I need to completely remove OpenSSL and then  
install from source. Great now OpenSSL is the newest version! But  
crap.....

OpenSSL::Cipher::Cipher.new("AES-128-CTR")

it says not a supported cipher (and I tried 256 and lower case also just  
in case I made simple mistake here, but OFB and such still work so it is  
actually not recognizing the mode)

when I do

puts OpenSSL::VERSION

it says I run 1.0.1 which is good, seems things should work ?!

but when I run

OpenSSL::OPENSSL\_VERSION

it says OpenSSL 1.0.0e

so I think the problem may be this since it says 1.0.0e instead of 1.0.1  
(of course I have no idea the difference between running VERSION and  
OPENSSL\_VERSION , the documentation does not answer this well enough for  
me to exactly understand the distinction)

I have reinstalled ruby from source a dozen times now trying different  
things. I try to point it at the directory I install 1.0.1 to with  
--with-openssl-dir=/path/to/openssl as I see many suggest and it has no  
idea what I am talking about (invalid option in new version of Ruby it  
seems).

I try for hours now to get ruby to work with the new version of openssl  
so I can use CTR mode but nothing I do works and I really can't think of  
what else I could possibly try at this point, and no amount of google is  
helping I have exhausted the pages.

Again thanks for your help sorry if I sound a bit irritated in this post  
but omfg why so hard to do such a simple thing 0\_0

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [1 April 2012 01:24 UTC](https://rubytalk.org/t/ruby-openssl-ecc-help-plz/65162/5 "2012-04-01T01:24:22Z")

</div>

Also from OpenSSL if I have it list the algorithms it supports it does  
not list aes-128-ctr, however if I type aes-128-ctr in it treats it like  
it exists (unlike if I type in aes-128-abc)

sorry that this thread has potentially gone off the topic of Ruby, the  
problem could very well be with OpenSSL but the thing is I can at this  
point not even surely identify where the problem is...something going  
screwy with OpenSSL? Ruby not seeing the new version of OpenSSL (it  
still shows 1.0.0e for some commands as I show previously)? Ruby not  
understanding that ctr mode is supported now since OpenSSL doesn't list  
it (even though it does work with it if it is typed in from console?)

it seems as likely to be a problem with Ruby to me as a problem with  
OpenSSL at this point, although in either case it is probably a user  
error on my part. Have you actually gotten ruby to work with ctr mode?

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [1 April 2012 03:45 UTC](https://rubytalk.org/t/ruby-openssl-ecc-help-plz/65162/6 "2012-04-01T03:45:25Z")

</div>

yes I didn't read your post before I made my second post (which I tried  
to delete).

it gets stuck with this error I try to recompile everything with fPIC  
flag but it still happens

/usr/bin/ld: /usr/local/ssl/lib/libcrypto.a(e\_gost\_err.o): relocation  
R\_X86\_64\_32 against `.data' can not be used when making a shared object;  
recompile with -fPIC  
/usr/local/ssl/lib/libcrypto.a: could not read symbols: Bad value  
collect2: ld returned 1 exit status

I think I am probably just going to stick with OFB, and avoid the  
headaches of trying to update OpenSSL and get it to work with Ruby.  
Maybe some day my distro will have 1.0.1 in the repository :\<

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [1 April 2012 15:20 UTC](https://rubytalk.org/t/ruby-openssl-ecc-help-plz/65162/7 "2012-04-01T15:20:44Z")

</div>

make clean is my friend

thanks! all is good now.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [11 April 2012 13:13 UTC](https://rubytalk.org/t/ruby-openssl-ecc-help-plz/65162/8 "2012-04-11T13:13:16Z")

</div>

I have a question about ECDH and I will put it here since there is no  
need to make two threads.

dh\_compute\_key(pub.public\_key)

returns a string. I need the integer value. .to\_i doesn't work. How can  
I get the integer value?

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [12 April 2012 11:14 UTC](https://rubytalk.org/t/ruby-openssl-ecc-help-plz/65162/9 "2012-04-12T11:14:05Z")

</div>

Yes, what I am implementing requires me to treat the shared secret as an  
integer. I think I might be kind of close to figuring it out:

q = OpenSSL::PKey::EC.new("secp128r2")  
q.generate\_key

pub = OpenSSL::PKey::EC.new(q.group)  
pub.public\_key = q.public\_key

a = pub.public\_key.to\_bn

ss = q.dh\_compute\_key(pub.public\_key)

puts ss.unpack('I\>\*')

this puts a series of numbers such as the following:

2755907301  
4161034086  
221727499  
1603331514

or

2041301904  
2634281936  
2269031273  
1943826378

Just to see if this works, I have then been combining these into big  
integers, so far just by hand. My theory is that if the resulting  
integer is the same bit size as the curve, that it is an indication I  
may not be doing it incorrectly. And I am so close to almost not  
certainly doing it wrong, because sometimes it does make output that  
equals 128 bits when I convert it to binary, for example

275590730141610340862217274991603331514

but alas sometimes it is slightly more or less than 128 bits, as with

2041301904263428193622690312731943826378

which is 131 bits

regardless of the curve I use the output is either the correct size or  
near it, but I don't understand the variation.

ss.length always returns a number of bytes that when multiplied by 8 is  
the size of the curve, assuming that the curve consists of a number of  
bits that is divisible by 8 anyway.

I could be way off on this and doing it totally wrong, but since I hit a  
total dead end I figured that I might as well try doing things until I  
at least get the correct size integer and then try to confirm it as  
being correct further from there, but I can just get close.

thanks :).

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Martin\_Bosslet1](https://avatars.discourse-cdn.com/v4/letter/m/90db22/32.png) [@Martin\_Bosslet1](https://rubytalk.org/u/Martin_Bosslet1)\
**Post date:** [31 March 2012 12:53 UTC](https://rubytalk.org/t/ruby-openssl-ecc-help-plz/65162/10 "2012-03-31T12:53:00Z")

</div>

Ruby's Cipher class supports whatever OpenSSL's EVP\_CIPHER interface  
supports. Unfortunately, CTR mode never made it there until just recently.  
Now finally, 1.0.1 supports AES in CTR mode. If you are interested in using  
it, you may want to upgrade to 1.0.1 and then you can also use it from Ruby  
like this:

cipher = OpenSSL::Cipher.new('aes-128-ctr')  
...

Regards,  
Martin

> **···**
>
> Am 31. März 2012 12:04 schrieb no name \<lists@ruby-forum.com\>:
> 
> > Thanks I have it working now. I have one other question, why doesn't  
> > ruby openssl support counter mode of operation??

---

<div class="post-metadata">

**Author:** ![Martin\_Bosslet1](https://avatars.discourse-cdn.com/v4/letter/m/90db22/32.png) [@Martin\_Bosslet1](https://rubytalk.org/u/Martin_Bosslet1)\
**Post date:** [1 April 2012 01:17 UTC](https://rubytalk.org/t/ruby-openssl-ecc-help-plz/65162/11 "2012-04-01T01:17:34Z")

</div>

The problem is that when you recompile Ruby with --with-openssl-dir,  
this won't get passed through to the step when the actual OpenSSL  
extension will be built. You could upgrade your OpenSSL on the OS  
level, but you probably don't want to if it's not in the package system  
yet. Then things would work automagically, but you can still get  
1.0.1 support with a custom OpenSSL installation:

Ruby OpenSSL is a C extension that has its own build process  
using an extconf.rb file. So what you can do is go to your Ruby  
source directory, and there to ext/openssl.  
Run  
&nbsp;&nbsp;ruby extconf.rb --with-openssl-dir=/path/to/openssl1.0.1  
then  
&nbsp;&nbsp;make  
This will produce openssl.so. Take that file and go to the directory  
where your Ruby installation lives, there you go to  
&nbsp;&nbsp;&nbsp;lib/ruby/1.9.\<x\>/i686 (32bit)  
or  
&nbsp;&nbsp;lib/ruby/1.9.x/x86\_64... (64 bit, depends on your OS, you'll only find  
native libraries in it)

and replace the file openssl.so (or .dynlib or .dll) with the one you just  
compiled.

Now `ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION` should  
print the desired 1.0.1.

-Martin

> **···**
>
> Am 1. April 2012 02:57 schrieb randompasswords arenotgoodidea \<lists@ruby-forum.com\>:
> 
> > thanks for the help. I am having a hellish time getting ruby to  
> > recognize the updated openSSL. First I compile new one from source,  
> > since it is not in the repository of my OS. After I compile the new  
> > version OpenSSL still thinks it is (and therefor is...) the old version  
> > that came with my OS. So I need to completely remove OpenSSL and then  
> > install from source. Great now OpenSSL is the newest version! But  
> > crap.....
> > 
> > OpenSSL::Cipher::Cipher.new("AES-128-CTR")
> > 
> > it says not a supported cipher (and I tried 256 and lower case also just  
> > in case I made simple mistake here, but OFB and such still work so it is  
> > actually not recognizing the mode)
> > 
> > when I do
> > 
> > puts OpenSSL::VERSION
> > 
> > it says I run 1.0.1 which is good, seems things should work ?!
> > 
> > but when I run
> > 
> > OpenSSL::OPENSSL\_VERSION
> > 
> > it says OpenSSL 1.0.0e
> > 
> > so I think the problem may be this since it says 1.0.0e instead of 1.0.1  
> > (of course I have no idea the difference between running VERSION and  
> > OPENSSL\_VERSION , the documentation does not answer this well enough for  
> > me to exactly understand the distinction)
> > 
> > I have reinstalled ruby from source a dozen times now trying different  
> > things. I try to point it at the directory I install 1.0.1 to with  
> > --with-openssl-dir=/path/to/openssl as I see many suggest and it has no  
> > idea what I am talking about (invalid option in new version of Ruby it  
> > seems).
> > 
> > I try for hours now to get ruby to work with the new version of openssl  
> > so I can use CTR mode but nothing I do works and I really can't think of  
> > what else I could possibly try at this point, and no amount of google is  
> > helping I have exhausted the pages.
> > 
> > Again thanks for your help sorry if I sound a bit irritated in this post  
> > but omfg why so hard to do such a simple thing 0\_0

---

<div class="post-metadata">

**Author:** ![Martin\_Bosslet1](https://avatars.discourse-cdn.com/v4/letter/m/90db22/32.png) [@Martin\_Bosslet1](https://rubytalk.org/u/Martin_Bosslet1)\
**Post date:** [1 April 2012 01:29 UTC](https://rubytalk.org/t/ruby-openssl-ecc-help-plz/65162/12 "2012-04-01T01:29:34Z")

</div>

> it seems as likely to be a problem with Ruby to me as a problem with  
> OpenSSL at this point, although in either case it is probably a user  
> error on my part. Have you actually gotten ruby to work with ctr mode?

Yes, I got it working here. I'm very confident you're having the problem I  
described in my previous response, applying the steps there should solve  
the problem.

---

<div class="post-metadata">

**Author:** ![Martin\_Bosslet1](https://avatars.discourse-cdn.com/v4/letter/m/90db22/32.png) [@Martin\_Bosslet1](https://rubytalk.org/u/Martin_Bosslet1)\
**Post date:** [12 April 2012 10:15 UTC](https://rubytalk.org/t/ruby-openssl-ecc-help-plz/65162/13 "2012-04-12T10:15:00Z")

</div>

Just to make sure - the computed secret is the x coordinate of some point,  
and what you would like to have is an integer representation of that?

-Martin

> **···**
>
> Am 11. April 2012 15:13 schrieb ruby ismyname \<lists@ruby-forum.com\>:
> 
> > I have a question about ECDH and I will put it here since there is no  
> > need to make two threads.
> > 
> > dh\_compute\_key(pub.public\_key)
> > 
> > returns a string. I need the integer value. .to\_i doesn't work. How can  
> > I get the integer value?
