Ruby openssl ECC help plz

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/.

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>:

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/.

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/.

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/.

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/.

make clean is my friend

thanks! all is good now.

···

--
Posted via http://www.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?

···

--
Posted via http://www.ruby-forum.com/.

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/.

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??

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
  ruby extconf.rb --with-openssl-dir=/path/to/openssl1.0.1
then
  make
This will produce openssl.so. Take that file and go to the directory
where your Ruby installation lives, there you go to
   lib/ruby/1.9.<x>/i686 (32bit)
or
  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

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.

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?