问题描述
我使用 Wei Dai 的 Crypto++ 在我的应用程序中创建了一个 ECDSA 密钥对 (secp128r1).签名和验证按预期工作.我不会将消息本身添加到签名中以最小化签名长度(正好是 32 字节).
I create an ECDSA keypair (secp128r1) in my application with Wei Dai's Crypto++. Signing and verifying works as expected. I do not add the message itself to the signature to minimize the signature length (which is exactly 32 Bytes).
但是,当我使用 openssl 创建签名时:
However, when I create the signature with openssl:
$ cat test.txt | openssl dgst -ecdsa-with-SHA1 -sign sample.key -keyform DER > act.bin
OpenSSL 显然将消息本身置于签名中,从而产生更大的签名(例如 39 字节).如果我设置了 CryptoPP::SignatureVerificationFilter::PUT_MESSAGE
,我可以使用 Crypto++ 验证签名.
OpenSSL obviously puts the message itself to the signature resulting in a larger signature (e.g. 39 Bytes). I can verify the signature with Crypto++ if I set CryptoPP::SignatureVerificationFilter::PUT_MESSAGE
.
我可以告诉 OpenSSL 在不将消息放入签名的情况下对消息进行签名,从而使生成的签名正好为 32 字节吗?
Can I tell OpenSSL to sign a message with NOT putting the message to the signature such that the resulting signature is 32 Byte exactly?
推荐答案
CodesInChaos 是正确的.签名中的额外字节来自 ASN.1 编码,而不是被签名的原始消息.例如,这里是一个 39 字节的签名,使用 ECDSA 密钥生成,曲线为 secp128r1:
CodesInChaos is correct. The extra bytes in the signature are from the ASN.1 encoding, and not the original message being signed. For example, here is a 39 byte signature generated with an ECDSA key with curve secp128r1:
30 25 02 10 4E 32 32 90 CA D9 BD D2 5F 8B BE 3B
F2 BF E9 7F 02 11 00 A7 83 A6 68 AD 74 7E 1A 0E
8F 73 BD DF 7A E8 B5
30 表示后面跟着一个序列.25 告诉您 Sequence 的长度为 0x25 字节.02 表示序列中的第一项是整数.10 告诉你第一个整数是 0x10 字节长.以下 0x10 (16) 字节是 ECDSA 签名的r"值.在第一个整数之后是字节 02.这告诉您序列的第二个整数即将开始.11 告诉您接下来的 0x11 (17) 个字节组成了第二个整数,它是 ECDSA 签名的s"值.它是 11 个字节,因为整数的第一个字节是 00.只要整数的第一个字节 >= 0x80,就会插入00".这是为了避免最高有效位为 1,这表示负整数.
The 30 indicates that a Sequence follows. The 25 tells you that the Sequence is 0x25 bytes long. The 02 indicates that the first item in the Sequence is an Integer. The 10 tells you that the first Integer is 0x10 bytes long. The following 0x10 (16) bytes are the "r" value of the ECDSA signature. Following the first integer is the byte 02. This tells you that the 2nd Integer of the Sequence is about to begin. 11 tells you that the next 0x11 (17) bytes make up the 2nd Integer, which is the "s" value of the ECDSA signature. It's 11 bytes because the first byte of the Integer is 00. "00" is inserted whenever the first byte of an integer is >= 0x80. This is to avoid the most significant bit being a 1, which would indicate a negative integer.
毕竟,真正的签名值是:
So after all that, the real signature values are:
r: 4E 32 32 90 CA D9 BD D2 5F 8B BE 3B F2 BF E9 7F
s: A7 83 A6 68 AD 74 7E 1A 0E 8F 73 BD DF 7A E8 B5
额外"字节用于 ASN.1 格式.
The "extra" bytes are for ASN.1 formatting.
这篇关于ECDSA 使用 OpenSSL 签名,使用 Crypto++ 验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!