使用prime256v1和已知的公钥创建新的OpenSSL EC Point

时间:2018-11-26 20:05:22

标签: ruby openssl

我正在尝试使用以下代码将已知的公钥转换为OpenSSL::PKey::EC::Point的实例:

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)

错误发生在最后一行,抛出:

`initialize': invalid encoding (OpenSSL::PKey::EC::Point::Error)

我运行Base64.encode64,然后将每个字节转换为十六进制表示形式,因为从周围读取似乎十六进制字符串是创建新BigNum的常用方法。

我猜想这是我对公钥信息做错的事情,因为ec_group的创建没有受到投诉。

1 个答案:

答案 0 :(得分:1)

首先,该字符串已经进行了base64编码,因此您需要对其进行 de 编码,而不是对其进行 en 编码:

decoded_public = Base64.decode64(public)

您得到的结果是包含密钥的DER编码结构,因此尝试直接查看字节并不会带您到任何地方(您可以使用OpenSSL::ASN1.decode(decoded_public)看到它包含的内容)。

不过,您可以直接在decoded_public上使用OpenSSL::PKey::read,这将为您提供一个OpenSSL::PKey::EC对象(具有正确的组)。要获取关联点,您只需致电public_key

key = OpenSSL::PKey.read decoded_public
point = key.public_key

结果是一个OpenSSL::PKey::EC::Point对象。