加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Ruby / openssl:将Elliptic Curve point八位字节串转换为OpenSS

发布时间:2020-12-16 19:08:55 所属栏目:百科 来源:网络整理
导读:我正在尝试编写 Ruby代码来检查我发现的特定消息上的椭圆曲线数字签名算法(ECDSA)签名 here. 问题是我不知道如何将公钥的八位字符串转换为OpenSSL::PKey::EC::Point对象.如果我用C语言写这个,我只是将八位字节串传递给OpenSSL的 o2i_ECPublicKey ,它做了一些
我正在尝试编写 Ruby代码来检查我发现的特定消息上的椭圆曲线数字签名算法(ECDSA)签名 here.

问题是我不知道如何将公钥的八位字符串转换为OpenSSL::PKey::EC::Point对象.如果我用C语言写这个,我只是将八位字节串传递给OpenSSL的o2i_ECPublicKey,它做了一些接近我想要的东西,实际上是reference implementation使用的.但是,我搜索了source code of Ruby (MRI)并且它不包含对o2i_ECPublicKey的调用所以我不知道如何在没有编写C扩展的情况下从Ruby中使用该函数.

这是八位字节的八位字符串.它只是一个0x04字节,后跟两个32字节整数,表示椭圆曲线上点的x和y坐标:

04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284

那么有谁知道如何将该字符串转换为Ruby中的OpenSSL :: PKey :: EC :: Point?一旦我得到了点对象,我将在下面的代码中使用它,我相信它将验证签名:

key = OpenSSL::PKey::EC.new('secp256k1')
key.public_key = point
result = key.dsa_verify_asn1(digest,signature)

更新:

感谢Jay-Ar Polidario,我得到了它的工作.以下是我使用OpenSSL验证签名的完整代码.我还写了一个名为ecdsa的宝石,并且我提供了代码,展示了如何使用我的宝石做同样的事情.

# coding: ASCII-8BIT

digest =
  "xbfx91xfbx0bx4fx63x33x77x4ax02x2bxd3x07x8exd6xcc" 
  "xd1x76xeex31xedx4fxb3xf9xafxcexb7x2ax37xe7x87x86"

signature_der_string =
  "x30x45" 
  "x02x21x00" 
  "x83x89xdfx45xf0x70x3fx39xecx8cx1cxc4x2cx13x81x0f" 
  "xfcxaex14x99x5bxb6x48x34x02x19xe3x53xb6x3bx53xeb" 
  "x02x20" 
  "x09xecx65xe1xc1xaaxeexc1xfdx33x4cx6bx68x4bxdex2b" 
  "x3fx57x30x60xd5xb7x0cx3ax46x72x33x26xe4xe8xa4xf1"

public_key_octet_string =
  "x04" 
  "xfcx97x02x84x78x40xaaxf1x95xdex84x42xebxecxedxf5" 
  "xb0x95xcdxbbx9bxc7x16xbdxa9x11x09x71xb2x8ax49xe0" 
  "xeaxd8x56x4fxf0xdbx22x20x9ex03x74x78x2cx09x3bxb8" 
  "x99x69x2dx52x4ex9dx6ax69x56xe7xc5xecxbcxd6x82x84"

# Verifying with openssl.
require 'openssl'
ec = OpenSSL::PKey::EC.new('secp256k1')
key_bn = OpenSSL::BN.new(public_key_octet_string,2)  # 2 means binary
ec.public_key = OpenSSL::PKey::EC::Point.new(ec.group,key_bn)
result = ec.dsa_verify_asn1(digest,signature_der_string)
puts result  # => true

# Verifying with the new ECDSA gem I wrote,version 0.1.5
require 'ecdsa'
group = ECDSA::Group::Secp256k1
point = ECDSA::Format::PointOctetString.decode(public_key_octet_string,group)
signature = ECDSA::Format::SignatureDerString.decode(signature_der_string)
result = ECDSA.valid_signature?(point,digest,signature)
puts result  # => true

我认为OpenSSL让你暂时将公钥表示为单个BN(大数字)是很奇怪的,因为它实际上是两个大数字.我的gem可以直接将八位字符串(如SEC2标准中所定义)转换为ECDSA :: Point对象.

解决方法

尝试以下(测试没有错误):
key =  '04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284'
key_bn = OpenSSL::BN.new(key,16) #Input: 16=Hexa,Output: BigNumber
group = OpenSSL::PKey::EC::Group.new('secp256k1')

point = OpenSSL::PKey::EC::Point.new(group,key_bn)
#--> <OpenSSL::PKey::EC::Point:0x5288178>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读