Я написал оболочку для OpenSSL, которая поддерживает ECC.Я пытаюсь прочитать закрытый ключ, сгенерированный с помощью
openssl ecparam -name secp384r1 -genkey -noout -out privkey.pem
, и сравнить его с тем, что OpenSSL выдаст после считывания ключа в EVP_PKEY
и EC_KEY
и печати его снова в строку,Результаты после прочтения не совпадают.
Короче говоря:
- Считайте ключ
- Сохраните его в
EVP_PKEY
- Напишите егоснова
И результаты не совпадают.Моя программа довольно большая, поэтому я создал MCVE, который демонстрирует проблему .
Я подозреваю, что проблема возникает из-за того, что я читаю в EC_KEY
, а затем пишу из EVP_PKEY
, что является общим.Я предполагаю здесь, потому что вход говорит, что это EC, но выход не говорит это.Я не уверен, как решить эту проблему, потому что я не вижу способа записи непосредственно из EC_KEY
в файл (био-объект).Является ли моя оценка правильной?
Пожалуйста, сообщите.
РЕДАКТИРОВАТЬ: меня попросили поместить весь код здесь в комментариях, так что вы идете:
#include <iostream>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/ec.h>
#include <openssl/pem.h>
EC_KEY* ecKey = nullptr;
EVP_PKEY* pkey = nullptr;
void setPrivateKeyFromPEM(const std::string& pemkey)
{
pkey = EVP_PKEY_new();
BIO* bio = BIO_new(BIO_s_mem());
int bio_write_ret = BIO_write(
bio, static_cast<const char*>(pemkey.c_str()), pemkey.size());
if (bio_write_ret <= 0) {
throw std::runtime_error("error1");
}
if (!PEM_read_bio_PrivateKey(bio, &pkey, NULL, NULL)) {
throw std::runtime_error("error1.5");
}
EC_KEY* eckey_local = EVP_PKEY_get1_EC_KEY(pkey);
if (!eckey_local) {
throw std::runtime_error("error2");
} else {
ecKey = eckey_local;
EC_KEY_set_asn1_flag(ecKey, OPENSSL_EC_NAMED_CURVE);
}
}
std::string getPrivateKeyAsPEM()
{
if (!pkey) {
throw std::runtime_error("error3");
}
BIO* outbio = BIO_new(BIO_s_mem());
if (!PEM_write_bio_PrivateKey(outbio, pkey, NULL, NULL, 0, 0,
NULL)) {
throw std::runtime_error("error4");
}
std::string keyStr;
int priKeyLen = BIO_pending(outbio);
keyStr.resize(priKeyLen);
BIO_read(outbio, (void*)&(keyStr.front()), priKeyLen);
return keyStr;
}
int main()
{
std::string expectedPrivKey =
"-----BEGIN EC PRIVATE KEY-----\n"
"MIGkAgEBBDBNK0jwKqqf8zkM+Z2l++9r8bzdTS/XCoB4N1J07dPxpByyJyGbhvIy\n"
"1kLvY2gIvlmgBwYFK4EEACKhZANiAAQvPxAK2RhvH/k5inDa9oMxUZPvvb9fq8G3\n"
"9dKW1tS+ywhejnKeu/48HXAXgx2g6qMJjEPpcTy/DaYm12r3GTaRzOBQmxSItStk\n"
"lpQg5vf23Fc9fFrQ9AnQKrb1dgTkoxQ=\n"
"-----END EC PRIVATE KEY-----\n";
setPrivateKeyFromPEM(expectedPrivKey);
// compare priv key
{
std::string privKeyRead = getPrivateKeyAsPEM();
std::cout << privKeyRead << std::endl;
std::cout<<expectedPrivKey<<std::endl;
}
return 0;
}