В настоящее время у меня возникают проблемы при подписании / проверке строки с помощью Crypto ++. Я пробовал методы, перечисленные на этом сайте среди других, в течение нескольких месяцев, но безуспешно. Ранее я пробовал решение в стиле C, опубликованное здесь: http://www.cryptopp.com/wiki/Elliptic_Curve_Digital_Signature_Algorithm, но в настоящее время я работаю над реализацией с использованием фильтров.
Моя попытка ниже является модификацией решения, размещенного здесь: Получить подпись ECDSA с Crypto ++.
Следующий код выводит ошибку:
ERROR: VerifierFilter: digital signature not valid
ECDSA<ECP, SHA256>::PrivateKey privateKey;
ECDSA<ECP, SHA256>::PublicKey publicKey;
AutoSeededRandomPool prng, rrng;
privateKey.Initialize(prng, CryptoPP::ASN1::secp256k1());
privateKey.MakePublicKey(publicKey);
string signature;
signature.erase();
string message = "Do or do not. There is no try.";
StringSource(message, true,
new SignerFilter(rrng,
ECDSA<ECP, SHA256>::Signer(privateKey),
new StringSink(signature)));
try
{
StringSource(signature + message, true,
new SignatureVerificationFilter(
ECDSA<ECP, SHA256>::Verifier(publicKey), NULL,
SignatureVerificationFilter::THROW_EXCEPTION
) // SignatureVerificationFilter
); // StringSource
}
catch (CryptoPP::Exception& e)
{
std::cerr << "\n\nERROR: " << e.what() << std::endl;
}
Любая помощь приветствуется, спасибо.
После более длительного просмотра вики я думаю, что, возможно, наткнулся на решение.
http://www.cryptopp.com/wiki/SignatureVerificationFilter#Signature_Generation_and_Verification
В приведенном выше примере фильтр получает конкатенацию
сообщение + подпись. Когда SIGNATURE_AT_BEGIN не указан в
конструктор, SIGNATURE_AT_END подразумевается и подпись будет
проверено должно быть представлено после сообщения. Если подпись
вставленный первым, SIGNATURE_AT_BEGIN должен быть указан как
значение дополнительных флагов, как показано ниже.
Так как THROW_EXCEPTION
используется, signature
а также message
должны поменяться местами или SIGNATURE_AT_BEGIN
должен быть добавлен. В этом случае следующий код не вызывает исключение.
StringSource ss(signature + message, true,
new SignatureVerificationFilter(
verifier, NULL,
THROW_EXCEPTION | SIGNATURE_AT_BEGIN
) // SignatureVerificationFilter
); // StringSource
StringSource(signature + message, true,
new SignatureVerificationFilter(
ECDSA<ECP, SHA256>::Verifier(publicKey), NULL,
SignatureVerificationFilter::THROW_EXCEPTION
) // SignatureVerificationFilter
); //
Выше выглядит подозрительно. Это выглядит подозрительно по двум причинам. Во-первых, он использует анонимные объявления, и я знаю, что некоторые версии GCC дают с ними плохие результаты. GCC генерирует код так, что деструкторы запускаются слишком рано. Так назови свою декларацию.
Во-вторых, SignatureVerificationFilter
берет ссылку, а не временную. Таким образом, вы должны предоставить ссылку на verifier
или используйте Ref()
функция-член, если она доступна.
Сначала попробуйте просто:
ECDSA<ECP, SHA256>::Verifier verifier(publicKey);
StringSource ss(signature + message, true,
new SignatureVerificationFilter(
verifier, NULL,
SignatureVerificationFilter::THROW_EXCEPTION
) // SignatureVerificationFilter
); // StringSource
Во-вторых, попробуйте с:
StringSource ss(signature + message, true,
new SignatureVerificationFilter(
ECDSA<ECP, SHA256>::Verifier(publicKey).Ref(), NULL,
SignatureVerificationFilter::THROW_EXCEPTION
) // SignatureVerificationFilter
); // StringSource
Но я не уверен, если ECDSA<ECP, SHA256>::Verifier(publicKey).Ref()
собирается на работу.