我试图生成“原始”,未编码的ECDSA签名,用于加密芯片。其目的是在主机pc上签名,然后发送到芯片上进行验证。然而,我遇到了一个小问题。我的理解是,ECDSA签名应该是64字节(对于secp256v1)。而且,当我使用芯片生成一个签名时,它的长度实际上是64字节。但是,当我使用openssl时,签名长度为71字节。签名的开头似乎是某种前缀,但我找不到任何关于这是什么的数据。
以下是我要做的每件事:
生成密钥:
openssl ecparam -genkey -name secp256r1 -noout -out privkeyv1.pem生成要签名的“消息”:
echo -n "Hello World" > test.txt我尝试过两种方法来签署这条消息。两者都会导致相同的、意想不到的输出。
第一个方法-生成测试文件的sha256散列,然后签名:
sha256sum test.txt | cut -f 1 -d " " > hash用pkutil签名
openssl pkeyutl -sign -in hash -inkey privkeyv1.pem -out test_sig_meth1方法2:使用openssl签名
openssl dgst -sha256 -binary -sign privkeyv1.pem -out test_sig_meth2 test.txt问题:这是xxd -p -c 256 test_sig_meth1:3045022000a86fb146d5f8f6c15b962640bc2d1d928f5e0f96a5924e4db2853ec8b66fb002210085431613d0a235db1adabc090cc1062a246a78941972e298423f4b3d081b48c8的输出
以及xxd -p -c 256 test_sig_meth2:30450220693732cd53d9f2ba3deae213d74cdf69a00e7325a10ddc6a4445ff2b33f95e62022100b6d2561e3afba10f95247ed05f0c59620dc0913f0d798b4148e05c4116b6384e的输出
正如您所看到的,这两个方法在开头都生成一些看起来类似头字节的字节( 30450220,可能更长),但我不知道它们是为了什么,也不知道如何删除它们。作为参考,这里是在密码芯片上生成的相同方法的签名。如果删除末尾的空字节填充,则为64个字节。4677AD09F2AF49D7445ED5D6AC7253ADC863EC6D5DB6D3CFBF9C6D3E221D0A7BA2561942524F46B590AEE749D827FBF80A961E884E3A7D85EC75FE48ADBC0BD00000000000000000000000
问题:如何使用openssl生成一个64字节原始(未编码,没有头) ECDSA签名,我可以使用这个方案?
发布于 2017-06-28 21:59:04
出于效率原因,大多数芯片只将r和s输出为字节数组或八进制字符串,其中每个r和s与八进制中的字段大小(即键大小)相同。另一种方法是将r和s输出为数字序列,因为最终,这就是r和s。使用ASN.1,这将成为一个整数值序列。
要从这样的序列进行转换,您可以首先使用BER解析器进行BER解码,以检索整数。然后实现一个I2OSP算法(整数到八位流原语),它需要以字节/八进制为参数的值和键大小。数字应该是大整数形式,但这很好,因为ASN.1误码率编码的整数也是大整数。基本上,如果数字太小,就必须留下零字节的pad。然后你把号码连在一起。
我不会进入OS2IP,它将字节数组转换为整数。请注意,如果以BER形式对其进行编码,则不应将整数填充为零字节。所以还需要一些诡计。
因此,尽管签名更改了表单,但签名仍然有效;您可以简单地在一个表单和另一个表单之间进行转换,签名仍然会验证--显然,只要您在作业中使用正确的库。
https://stackoverflow.com/questions/44807170
复制相似问题