使用 Crypto++ 将签名从 P1363 转换为 ASN.1/DER 格式?
Convert signature from P1363 to ASN.1/DER format using Crypto++?
我有一个这样创建的签名:
size_t siglenth = _signer.MaxSignatureLength();
QByteArray signature(siglenth, 0x00);
signature.reserve(siglenth);
siglenth = _signer.SignMessage(_prng,
(const CryptoPP::byte*) (message.constData()),
message.length(), (CryptoPP::byte*) signature.data());
我的签名大小为 64,包含:
ECCD530E5F232B7C566CA5322F990B3D55ED91156DF3845C4B9105BFE57606DDD68F332A0A5BF7CAB673E4970D10109B72F114571E7474F93ED7C89CD1B89AD4
根据我在 dsa.h
文件中阅读的内容,此签名当前采用 DSA_P1363
格式。我需要将其转换为 DSA_DER
格式。
要执行此操作,我尝试:
QByteArray derSign(70, 0xFF);
size_t converted_size = CryptoPP::DSAConvertSignatureFormat(
(CryptoPP::byte*) (derSign.data()), sizeof(derSign.data()), CryptoPP::DSA_DER,
(CryptoPP::byte*) (signature.data()), sizeof(signature.data()), CryptoPP::DSA_P1363);
此转换的输出如下所示。它似乎只是签名的第一部分。它的大小为 8,包含:
300D020500ECCD53
怎么了?
谢谢。
The output of this convertion is curious, it seems to be only the
first part of the signature. It have a size of 8 and contains :
300D020500ECCD53
What is wrong ?
而不是:
size_t converted_size = DSAConvertSignatureFormat(
(byte*) (derSign.data()), sizeof(derSign.data()), DSA_DER,
(byte*) (signature.data()), sizeof(signature.data()), DSA_P1363);
你应该使用类似的东西:
size_t converted_size = DSAConvertSignatureFormat(
(byte*) (derSign.data()), derSign.size(), DSA_DER,
(const byte*) (signature.data()), signature.size(), DSA_P1363);
sizeof(derSign.data())
产生 sizeof
和 size_t
,这与字符串数据的大小不同。
此外,由于正在写入 derSign
,因此您需要一个非常量指针。几乎所有版本的 C++ 都使用第一个元素的地址来获取它:
size_t converted_size = DSAConvertSignatureFormat(
(byte*) (&derSign[0]), derSign.size(), DSA_DER,
(const byte*) (signature.data()), signature.size(), DSA_P1363);
几乎最后,这就是 P1363 中的内容,其中 r
和 s
是一个串联,每个都基于字段元素的大小和子组顺序:
[ r ] [ s ]
这就是您在 ASN.1/DER 中所需要的。有 3 个 ASN.1 对象——一个序列和两个整数。每个对象需要一个八位字节用于 ASN.1 类型,最多两个八位字节用于长度。 r
和 s
是字段元素的大小。每个 ASN.1 整数可能需要一个前导 0,因此为 r
和 s
添加两个额外的字节。
SEQUENCE = {
INTEGER r;
INTEGER s;
}
因此,对于 ASN.1/DER 缓冲区,您需要 3+3+3+COUNTOF(r)+1+COUNTOF(s)+1。
最后,代码段可能如下所示:
using namespace CryptoPP;
// ... Other gyrations
std::string derSign, signature;
// ...Calculate signature
// Make room for the ASN.1/DER encoding
derSign.resize(3+3+3+2+signature.size())
size_t converted_size = DSAConvertSignatureFormat(
(byte*) (&derSign[0]), derSign.size(), DSA_DER,
(const byte*) (signature.data()), signature.size(), DSA_P1363);
ASSERT(converted_size <= derSign.size());
derSign.resize(converted_size);
Crypto++ 现在在 wiki 上有一个页面 DSAConvertSignatureFormat
. There is an example of using DSAConvertSignatureFormat
at ECDSA | OpenSSL and Java,但转换是相反的。
(您的问题和缺乏文档有效地触发了错误,我们弥补了差距)。
我刚注意到这个...
size_t siglenth = _signer.SignatureLength();
QByteArray signature(siglenth, 0x00);
signature.reserve(siglenth);
siglenth = _signer.SignMessage(_prng, (const CryptoPP::byte*) (message.constData()),
message.length(), (CryptoPP::byte*) signature.data());
改用这个:
QByteArray signature;
size_t siglenth = _signer.SignatureLength();
signature.resize(siglenth);
siglenth = _signer.SignMessage(_prng,
(const byte*) (message.constData()), message.length(),
(byte*) (&signature[0]));
signature.resize(siglenth);
我有一个这样创建的签名:
size_t siglenth = _signer.MaxSignatureLength();
QByteArray signature(siglenth, 0x00);
signature.reserve(siglenth);
siglenth = _signer.SignMessage(_prng,
(const CryptoPP::byte*) (message.constData()),
message.length(), (CryptoPP::byte*) signature.data());
我的签名大小为 64,包含:
ECCD530E5F232B7C566CA5322F990B3D55ED91156DF3845C4B9105BFE57606DDD68F332A0A5BF7CAB673E4970D10109B72F114571E7474F93ED7C89CD1B89AD4
根据我在 dsa.h
文件中阅读的内容,此签名当前采用 DSA_P1363
格式。我需要将其转换为 DSA_DER
格式。
要执行此操作,我尝试:
QByteArray derSign(70, 0xFF);
size_t converted_size = CryptoPP::DSAConvertSignatureFormat(
(CryptoPP::byte*) (derSign.data()), sizeof(derSign.data()), CryptoPP::DSA_DER,
(CryptoPP::byte*) (signature.data()), sizeof(signature.data()), CryptoPP::DSA_P1363);
此转换的输出如下所示。它似乎只是签名的第一部分。它的大小为 8,包含:
300D020500ECCD53
怎么了?
谢谢。
The output of this convertion is curious, it seems to be only the first part of the signature. It have a size of 8 and contains :
300D020500ECCD53
What is wrong ?
而不是:
size_t converted_size = DSAConvertSignatureFormat( (byte*) (derSign.data()), sizeof(derSign.data()), DSA_DER, (byte*) (signature.data()), sizeof(signature.data()), DSA_P1363);
你应该使用类似的东西:
size_t converted_size = DSAConvertSignatureFormat(
(byte*) (derSign.data()), derSign.size(), DSA_DER,
(const byte*) (signature.data()), signature.size(), DSA_P1363);
sizeof(derSign.data())
产生 sizeof
和 size_t
,这与字符串数据的大小不同。
此外,由于正在写入 derSign
,因此您需要一个非常量指针。几乎所有版本的 C++ 都使用第一个元素的地址来获取它:
size_t converted_size = DSAConvertSignatureFormat(
(byte*) (&derSign[0]), derSign.size(), DSA_DER,
(const byte*) (signature.data()), signature.size(), DSA_P1363);
几乎最后,这就是 P1363 中的内容,其中 r
和 s
是一个串联,每个都基于字段元素的大小和子组顺序:
[ r ] [ s ]
这就是您在 ASN.1/DER 中所需要的。有 3 个 ASN.1 对象——一个序列和两个整数。每个对象需要一个八位字节用于 ASN.1 类型,最多两个八位字节用于长度。 r
和 s
是字段元素的大小。每个 ASN.1 整数可能需要一个前导 0,因此为 r
和 s
添加两个额外的字节。
SEQUENCE = {
INTEGER r;
INTEGER s;
}
因此,对于 ASN.1/DER 缓冲区,您需要 3+3+3+COUNTOF(r)+1+COUNTOF(s)+1。
最后,代码段可能如下所示:
using namespace CryptoPP;
// ... Other gyrations
std::string derSign, signature;
// ...Calculate signature
// Make room for the ASN.1/DER encoding
derSign.resize(3+3+3+2+signature.size())
size_t converted_size = DSAConvertSignatureFormat(
(byte*) (&derSign[0]), derSign.size(), DSA_DER,
(const byte*) (signature.data()), signature.size(), DSA_P1363);
ASSERT(converted_size <= derSign.size());
derSign.resize(converted_size);
Crypto++ 现在在 wiki 上有一个页面 DSAConvertSignatureFormat
. There is an example of using DSAConvertSignatureFormat
at ECDSA | OpenSSL and Java,但转换是相反的。
(您的问题和缺乏文档有效地触发了错误,我们弥补了差距)。
我刚注意到这个...
size_t siglenth = _signer.SignatureLength(); QByteArray signature(siglenth, 0x00); signature.reserve(siglenth); siglenth = _signer.SignMessage(_prng, (const CryptoPP::byte*) (message.constData()), message.length(), (CryptoPP::byte*) signature.data());
改用这个:
QByteArray signature;
size_t siglenth = _signer.SignatureLength();
signature.resize(siglenth);
siglenth = _signer.SignMessage(_prng,
(const byte*) (message.constData()), message.length(),
(byte*) (&signature[0]));
signature.resize(siglenth);