将DSA_P1363转换为DSA_DER

问题描述 投票:2回答:1

我有这样创建的签名:

// CryptoPP::AutoSeededRandomPool _prng;
// const QByteArray& message; // given from parameters

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

怎么了?

感谢。

c++ cryptography crypto++ der
1个回答
2
投票

此转换的输出很好奇,似乎只是签名的第一部分。它的大小为8,包含:

300D020500ECCD53

怎么了?

而不是:

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 a 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 ++现在在Wiki的DSAConvertSignatureFormat上有一个页面。有一个在DSAConvertSignatureFormat处使用DSAConvertSignatureFormat的示例,但转换是相反的。

((您的问题和文档不足实际上触发了一个错误,我们弥补了差距)。


我刚刚注意到了这个...

ECDSA | OpenSSL and Java

代替使用此:

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());

我不相信最终的QByteArray signature; size_t siglenth = _signer.MaxSignatureLength(); signature.resize(siglenth); siglenth = _signer.SignMessage(_prng, (const byte*) (message.constData()), message.length(), (byte*) (&signature[0])); signature.resize(siglenth); 对于resize签名方案(基于离散日志,例如ElGamal和DSA)不会有所不同。但是,最后的DL_*对于resize签名方案(基于基于活门功能的RW和RSA)有所不同。

© www.soinside.com 2019 - 2024. All rights reserved.