将OpenSSL的C实现转换为Ruby代码

时间:2018-12-01 11:24:54

标签: c ruby openssl

在C语言中,我可以执行以下操作:

bignum = BN_new();
BN_bin2bn(my_message, 32, bignum);
group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
ecp = EC_POINT_new(group);
check = EC_POINT_set_compressed_coordinates_GFp(group, ecp, bignum, 0, NULL);
key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
check = EC_KEY_set_public_key(key, ecp);
check = EVP_PKEY_set1_EC_KEY(public_key, key);

在Ruby中,我以为这样做会做同样的事情,但是我得到一个错误*

bignum = OpenSSL::BN.new(my_message, 2)
group = OpenSSL::PKey::EC::Group.new('prime256v1')
group.point_conversion_form = :compressed
public_key = OpenSSL::PKey::EC::Point.new(group, bignum)

在两种情况下,我都可以登录bignum并看到它是相同的,并且我非常肯定prime256v1是正确的组。

在两种情况下,C和Ruby都使用相同版本的OpenSSL(OpenSSL 1.0.2p,2018年8月14日)

任何有关我在这里做错事情的建议都会受到赞赏。

*我收到的错误消息是invalid encoding (OpenSSL::PKey::EC::Point::Error)

1 个答案:

答案 0 :(得分:2)

C语言中的EC_POINT_set_compressed_coordinates_GFp函数希望您传递该点的x坐标,并分别传递一个值以指定可能的两个点中的哪一个(您正在传递文字{{1} },实际上您应该确定实际值。

在Ruby中,0初始化程序期望将点编码为包含有关两个坐标的信息的字符串(我不知道这种格式是否具有名称,但这很常见,并且由{ {3}})。在压缩坐标的情况下,该字符串与C代码中的字符串基本相同,为32个字节,但开头有一个额外的字节,Point0x02,与传递{{1} }或0x03作为0的y位。

如果字符串不是以1EC_POINT_set_compressed_coordinates_GFp开头(对于未压缩的点不是0x02)或长度错误,则将出现0x03错误

看起来Ruby OpenSSL绑定似乎无法提供使用单独的x和y坐标指定点的方法。最简单的方法是将0x04invalid encoding前缀添加到字符串,然后再将其传递给0x02

如果已经有了此字符串,则可以在C语言中使用它来使用SECG创建一个点。 Ruby本身EC_POINT_oct2point,如果您将字符串传递给0x03