使用Openssl验证ECDSA签名

3

我想使用openssl创建并验证签名。

我希望我的签名有十六进制输出。

这是我的代码:

#create private key
openssl ecparam -genkey -name secp256k1 -rand /dev/urandom -noout -out private.pem

#public key derivation
openssl ec -in private.pem -pubout -out public.pem

#create signature
openssl dgst -sha256 -hex -sign private.pem msg.txt  > signature.hex

#check signature
openssl dgst -sha256 -verify public.pem -signature signature.hex msg.txt

我遇到了这个错误:
Error Verifying Data
4573216364:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1220:
4573216364:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:386:Type=ECDSA_SIG

如果我在创建签名时去掉-hex,它就可以工作。
$ openssl version
OpenSSL 1.0.2s  28 May 2019
2个回答

3

openssl dgst 命令的 "-hex" 参数表示输出的不是二进制,而是二进制输出的十六进制转储。

引用:

-hex

将摘要输出为十六进制转储。这是“普通”摘要的默认情况,而不是数字签名。有关使用 -hex 进行数字签名,请参阅下面的注释。

注释部分如下:

无法使用 openssl 验证十六进制签名。相反,使用“xxd -r”或类似程序将十六进制签名转换为二进制签名,然后再进行验证。

因此,如果您使用 -hex 选项进行十六进制转储,则需要在将其传递到 openssl 进行验证之前自行将其转换回二进制。


我遇到了与 OP 相同的错误,即使没有使用 -hex 标志.. 有什么想法吗? - mikew
如果您收到此错误,则某些原因导致签名损坏。因此,您必须查看从openssl传出的数据进入其存储(文件?)时发生了什么,并且它没有以任何方式更改。openssl期望签名文件以二进制格式输出自原始openssl命令。 - Shane Powell
我只是在执行OP在这里发布的openssl命令,减去-hex...我发现这个其他问题,在那里显然你必须hexedit签名,因为openssl输出不正确...看起来很麻烦: https://dev59.com/cLjoa4cB1Zd3GeqPFtv- - mikew
如果您的openssl.exe没有出现任何问题,那么问题就在于操作系统/控制台应用程序重定向管道到文件时不会破坏二进制输出。如果您的控制台应用程序假定输出是文本,则可能会破坏在Windows中写入文件的输出。 - Shane Powell
尝试在openssl中使用“-out <filename>”选项,以确保它与直接输出到文件无关。 - Shane Powell
我在另一个教程中看到了-out参数,但是在使用它时出现了“只能签署或验证一个文件”的错误... 我刚才再次尝试并将-out参数放在-sign参数之前,现在它可以工作了!非常感谢。 - mikew

0
复制自:如何在medtls库中使用ECDSA函数 从数学角度来说,ECDSA签名是一对整数(r,s)。函数mbedtls_ecdsa_sign将给出两个整数r和s作为输出,你可以决定如何输出这些整数。有两种常见的ECDSA签名表示方式:采用固定大小的r和s表示,并将这两个整数放在一起,或者将它们组装成ASN.1序列,通常以DER形式呈现(ASN.1接受多种表示方式,例如带或不带前导零,而DER是一种特定的ASN.1表示,不带前导零)。
OpenSSL同时具有ECDSA和Digest功能。我不确定当你使用OpenSSL digest时,是否实际上生成了ECDSA的“r”和“s”,即使你使用椭圆曲线密钥也是如此。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接