Я начинаю использовать openssl.
Я хочу использовать открытый ключ для проверки подписи. Но сейчас я не могу прочитать свой открытый ключ с помощью openssl.
Вот мой исходный код:
#include <iostream>
#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/err.h>
bool verifyPublicKey(const std::string &sRawPublicKey);
void printAllError();
int main(int argc, char* argv[])
{
if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " PUBLIC KEY" << std::endl;
return EXIT_FAILURE;
}
std::string sPublicKey = argv[1];
std::cout << "Key: " << sPublicKey << std::endl;
bool bRes = verifyPublicKey(sPublicKey);
if (!bRes)
{
std::cerr << "verifyPublicKey failled" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
bool verifyPublicKey(const std::string &sRawPublicKey)
{
bool bRes = false;
EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
EC_KEY_set_conv_form(eckey, POINT_CONVERSION_UNCOMPRESSED);
unsigned char *p_RawPublicKey = new unsigned char[sRawPublicKey.length() + 1];
std::copy(sRawPublicKey.begin(), sRawPublicKey.end(), p_RawPublicKey);
const unsigned char *pubkey_raw_p = p_RawPublicKey;
o2i_ECPublicKey(&eckey, &pubkey_raw_p, sRawPublicKey.size());
if (!EC_KEY_check_key(eckey))
{
EC_KEY_free(eckey);
bRes = false;
printAllError();
}
else
{
EC_KEY_free(eckey);
bRes = true;
}
return bRes;
}
void printAllError()
{
while (ERR_peek_last_error() != 0)
{
std::cerr << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
}
}
Я запускаю его со следующим открытым ключом:
3059301306072A8648CE3D020106082A8648CE3D03010703420004E297417036EB4C6404CC9C2AC4F28468DD0A92F2C9496D187D2BCA784DB49AB540B9FD9ACE0BA49C8532825954755EC10246A71AF2AEE9AEC34BE683CDDFD212
ASN.1 декодер:
SEQUENCE {
SEQUENCE {
OBJECTIDENTIFIER 1.2.840.10045.2.1 (ecPublicKey)
OBJECTIDENTIFIER 1.2.840.10045.3.1.7 (P-256)
}
BITSTRING 0x04E297417036EB4C6404CC9C2AC4F28468DD0A92F2C9496D187D2BCA784DB49AB540B9FD9ACE0BA49C8532825954755EC10246A71AF2AEE9AEC34BE683CDDFD212
: 0 unused bit(s)
}
В ASN.1 я замечаю, что ключ, который я использую, имеет правильный формат: 0x04 || HEX (x) || HEX (y) с z = 0x04.
Вывод программы следующий:
Ключ: 3059301306072A8648CE3D020106082A8648CE3D03010703420004E297417036EB4C6404CC9C2AC4F28468DD0A92F2C9496D187D2BCA784DB49AB540B9FD5322A5F5A5F5F5F5F5F5B5
ошибка: 10067066: процедуры эллиптической кривой: ec_GFp_simple_oct2point: неверное кодирование
ошибка: 10098010: процедуры эллиптической кривой: o2i_ECPublicKey: EC lib
ошибка: 1010206A: процедуры эллиптической кривой: ec_key_simple_check_key: точка в бесконечности verifyPublicKey не удалось
Я потерян. У вас есть объяснения?
Более того, возможно ли пойти дальше, указав только x и y (без заголовка ASN.1).
Спасибо