Разделение открытых и закрытых ключей пары ключей ECDSA

Я использую C ++, чтобы попытаться сгенерировать пару ключей ECDSA после Elliptic_Curve_Cryptography из OpenSSL вики.

#include <iostream>

#include <openssl/obj_mac.h>
#include <openssl/ec.h>

int main()
{
EC_KEY *key;

if(NULL == (key = EC_KEY_new_by_curve_name(NID_secp224r1)))
std::cout << "error on new_curve_by_name" << std::endl;

if(1 != EC_KEY_generate_key(key)) std::cout << "error in generating keys" << std::endl;
}

Пара ключей генерируется без ошибок, но я не знаю, как извлечь открытый и закрытый ключ в два разных объекта (EC_POINT и BIGNUM), вы понимаете?

2

Решение

Я думаю, что методы, которые вы хотите:

EC_KEY_get0_private_key а также
EC_KEY_get0_public_key

Это работает для меня:

EC_KEY* key = EC_KEY_new_by_curve_name(NID_secp224r1);

if(!key)
{
std::cerr << "Error creating curve key" << '\n';
return EXIT_FAILURE;
}

if(!EC_KEY_generate_key(key))
{
std::cerr << "Error generating curve key" << '\n';
EC_KEY_free(key);
return EXIT_FAILURE;
}

BIGNUM const* prv = EC_KEY_get0_private_key(key);
if(!prv)
{
std::cerr << "Error getting private key" << '\n';
EC_KEY_free(key);
return EXIT_FAILURE;
}

std::cout << "Private key: " << prv << '\n';

EC_POINT const* pub = EC_KEY_get0_public_key(key);
if(!pub)
{
std::cerr << "Error getting public key" << '\n';
EC_KEY_free(key);
return EXIT_FAILURE;
}

std::cout << "Public key: " << pub << '\n';

// Use keys here ...

EC_KEY_free(key);

НОТА:

Когда используешь C библиотеки, как это я часто определяю обычай умный указатель заботиться, если удаления. Это делает код менее подверженным утечкам памяти и «исключающим безопасность».

Например, я бы определил что-то вроде этого:

struct ec_key_dter{void operator()(EC_KEY* k)const{if(k) EC_KEY_free(k);}};
using  ec_key_uptr = std::unique_ptr<EC_KEY, ec_key_dter>;

И используйте это так:

auto key = ec_key_uptr(EC_KEY_new_by_curve_name(NID_secp224r1));

if(!key)
throw std::runtime_error("Error creating curve key");

if(!EC_KEY_generate_key(key.get()))
throw std::runtime_error("Error generating curve key");

if(!EC_KEY_check_key(key.get()))
throw std::runtime_error("Error checking curve key");

// ... etc ...

// Do not delete the key manually!!
3

Другие решения

Я думаю, что вы должны сделать следующее:

BIGNUM *privateKey;
EC_POINT *publicKey;

privateKey = BN_new();
EC_KEY_set_private_key(key, privateKey);
EC_KEY_set_public_key(key, publicKey);

РЕДАКТИРОВАТЬ :

Эти два вызова установят privateKey и publicKey соответственно.
Открытая документация SSL заявляет, что «пункт назначения должен быть вновь выделенным BIGNUM, полученным посредством вызова BN_new(), Он не должен был использоваться для других целей или инициализироваться каким-либо образом.«, следовательно, я добавляю BN_new() вызов.

Я не вижу ничего похожего на создание объекта EC_Point (если только вы не используете EC_Group для создания этого способа: EC_POINT *EC_POINT_new(const EC_GROUP *group);

Так что попробуйте это, если вы все еще не получаете его, то, возможно, вам следует посмотреть, как правильно создается объект EC_Point в соответствии с вашим использованием.

0

Это возвращает закрытый ключ как BIGNUM

BIGNUM* bn = EC_KEY_get0_private_key(key);

Для открытого ключа не уверен, как получить EC_POINT, но вы можете получить необработанные байты с чем-то вроде:

  // first call returns length of key
int len = i2o_ECPublicKey(key, 0);
std::vector<unsigned char> bytes b(len, 0);
unsigned char* p = &b[0];
// second call copies key into p (and returns length if successful)
if (i2o_ECPublicKey(key, &p)) != len)
{
// handle error
}
0
По вопросам рекламы [email protected]