使用 OpenSSL 进行 ECDSA 签名,使用 Crypto++ 进行验证

2022-01-10 00:00:00 cryptography openssl c++ ecdsa crypto++

我使用 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 编码,而不是被签名的原始消息.例如,这里是使用 ECDSA 密钥生成的 39 字节签名,曲线为 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 告诉您序列的长度为 0x25 个字节.02 表示序列中的第一项是整数.10 告诉您第一个 Integer 的长度为 0x10 个字节.下面的 0x10 (16) 个字节是 ECDSA 签名的r"值.第一个整数之后是字节 02.这告诉您序列的第二个整数即将开始.11 告诉您接下来的 0x11 (17) 个字节构成了第二个整数,即 ECDSA 签名的s"值.它是 11 个字节,因为 Integer 的第一个字节是 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.

相关文章