rsa_public_encrypt возвращает -1, ошибка 0x0406B07A

Я пытаюсь зашифровать данные с помощью RSA_public_encrypt, но это не работает (retEnc всегда равно -1). Я также попытался найти больше информации об ошибке, используя ERR_get_error и ERR_error_string.

Это код:

RSA *rsaPkey = NULL;

FILE *pemFile;
fopen_s(&pemFile, filename.c_str(), "r");
rsaPkey         = PEM_read_RSA_PUBKEY(pemFile, &rsaPkey, NULL, NULL);
fclose(pemFile);

if(rsaPkey == NULL)
    throw "Error pubkey file";

int size = RSA_size(rsaPkey);
unsigned char *encrypted;
encrypted = new unsigned char[size];

string instr  = "test";
int length = instr.length();
unsigned char *in = (unsigned char *)(instr.c_str());

unsigned long errorTrack = ERR_get_error() ;

int retEnc = RSA_public_encrypt(length, in, (unsigned char *)encrypted, rsaPkey, RSA_NO_PADDING);
errorTrack = ERR_get_error() ;
char *errorChar = new char[120];
errorChar = ERR_error_string(errorTrack, errorChar);

ERR_error_string дает мне error:0406B07A:lib(4):func(107):reason(122)

Как я могу найти более подробную информацию об этом, где я могу найти библиотеку 4 и функцию 107?

Когда я пытаюсь зашифровать с помощью openssl cli и того же файла открытого ключа, шифрование работает нормально.


person enzo    schedule 02.03.2018    source источник
comment
Вас также может заинтересовать инициализация библиотеки на вики OpenSSL.   -  person jww    schedule 02.03.2018


Ответы (1)


ERR_error_string gives me error:0406B07A:lib(4):func(107):reason(122)

Как я могу найти более подробную информацию об этом, где я могу найти библиотеку 4 и функцию 107?

Я считаю, что самый простой способ узнать больше из кода ошибки OpenSSL:

$ openssl errstr 0406B07A
error:0406B07A:rsa routines:RSA_padding_add_none:data too small for key size

char *errorChar = new char[120];
errorChar = ERR_error_string(errorTrack, errorChar);

Кроме того, на ERR_error_string справочной странице:

ERR_error_string() генерирует удобочитаемую строку, представляющую код ошибки e, и помещает ее в buf. buf должен иметь длину не менее 256 байт. Если buf равен NULL, строка ошибки помещается в статический буфер. Обратите внимание, что эта функция не является потокобезопасной и не проверяет размер буфера; вместо этого используйте ERR_error_string_n().

Поскольку вы используете С++, что-то вроде этого может быть проще:

std::string errorMsg;
errorMsg.resize(256);

(void)ERR_error_string(errorTrack, &errorMsg[0]);

Выше вы используете std::string для управления ресурсами. Чтобы получить неконстантный указатель, вы берете адрес первого элемента.

Если вы хотите, вы можете правильно изменить размер errorMsg с помощью:

(void)ERR_error_string(errorTrack, &errorMsg[0]);
errorMsg.resize(std::strlen(errorMsg.c_str()));

Вот еще один трюк, который может упростить использование C++.

typedef unsigned char byte;
...

std::string encrypted;
int size = RSA_size(rsaPkey);

if (size < 0)
    throw std::runtime_error("RSA_size failed");

// Resize to the maximum size
encrypted.resize(size);
...

int retEnc = RSA_public_encrypt(length, in, (byte*)&encrypted[0], rsaPkey, RSA_NO_PADDING);

if (retEnc < 0)
    throw std::runtime_error("RSA_public_encrypt failed");

// Resize the final string now that the size is known
encrypted.resize(retEnc );

Выше вы используете std::string для управления ресурсами. Чтобы получить неконстантный указатель, вы берете адрес первого элемента.

Кроме того, NO_PADDING обычно плохая идея. Обычно вам нужно заполнение OAEP. См. примечания на RSA_public_encrypt справочной странице о том, как отступы влияют на максимальный размер. .


C++ может упростить использование OpenSSL. Вы можете избежать явных вызовов таких функций, как EVP_CIPHER_CTX_free, используя unique_ptr. См. Симметричное шифрование и дешифрование EVP | Программы C++ в вики OpenSSL, unique_ptr и OpenSSL STACK_OF(X509)*, Как получить результат PKCS7_sign в char * или std::string и т. д.

В вашем случае похоже, что это было бы полезно для управления ресурсами:

using FILE_ptr = std::unique_ptr<FILE, decltype(&::fclose)>;
using RSA_ptr = std::unique_ptr<RSA, decltype(&::RSA_free)>;
person jww    schedule 02.03.2018