Вывод этого преобразования любопытен, кажется, что это только первая часть подписи.Он имеет размер 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, где 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 ++ теперь имеет страницу навики на DSAConvertSignatureFormat
.Есть пример использования DSAConvertSignatureFormat
в ECDSA |OpenSSL и 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);