我以这种方式创建了一个签名:

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,其中包含:



根据我在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,包含:



怎么了?

谢谢。

最佳答案



代替:



您应该使用类似:

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中所拥有的,其中rs是一个串联,并且每个都是基于字段元素的大小和子组顺序的:
[ r ] [ s ]

这是您在ASN.1/DER中需要的。有3个ASN.1对象-一个序列和两个整数。对于ASN.1类型,每个对象需要一个八位位组,而对于长度,每个对象最多需要两个八位位组。 rs是字段元素的大小。每个ASN.1整数可能需要前导0,因此请为rs添加两个额外的字节。
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++现在在wikit上的 DSAConvertSignatureFormat 上有一个页面。在ECDSA | OpenSSL and Java上有一个使用DSAConvertSignatureFormat的示例,但是转换是相反的。

(您的问题和缺少文档实际上触发了一个错误,因此我们缩小了差距)。

我只是注意到了这一点...



而是使用以下命令:
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);

关于c++ - 使用Crypto++将签名从P1363转换为ASN.1/DER格式?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58097935/

10-11 18:36