Reputation: 8792
I'm trying to turn a known public key into an instance of OpenSSL::PKey::EC::Point
with the following code:
require 'base64'
require 'openssl'
public = 'MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgAD5tgZhw82GpGYJYkWNgeDp/0OzT4y/YLS+tMpZeJ2VEQ='
decoded_public = Base64.encode64(public)
hex_string = decoded_public.each_byte.map { |b| b.to_s(16) }.join()
ec_group = OpenSSL::PKey::EC::Group.new('prime256v1')
key = OpenSSL::PKey::EC.new(ec_group)
bn = OpenSSL::BN.new(hex_string, 16)
point = OpenSSL::PKey::EC::Point.new(ec_group, bn)
The error occurs on the last line, throwing:
`initialize': invalid encoding (OpenSSL::PKey::EC::Point::Error)
I run Base64.encode64
and then turn each byte into a hex representation because from reading around it seems like hex strings are a common way of creating a new BigNum.
I'm guessing it is something I'm doing wrong with the public key information, because the ec_group
gets created without complaint.
Upvotes: 2
Views: 1159
Reputation: 79743
First of all, that string is already base64 encoded, so you need to decode it, not encode it:
decoded_public = Base64.decode64(public)
The result you get is a DER encoded structure containing the key, so trying to look at the bytes directly isn’t going to get you anywhere (you can see what it contains using OpenSSL::ASN1.decode(decoded_public)
).
You can however use OpenSSL::PKey::read
directly on decoded_public
, which will give you an OpenSSL::PKey::EC
object (with the correct group). To get the associated point you can just call public_key
:
key = OpenSSL::PKey.read decoded_public
point = key.public_key
The result is an OpenSSL::PKey::EC::Point
object.
Upvotes: 1