[英]rsa_public_encrypt returns -1, error 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和相同的公钥文件进行加密时,加密工作正常。
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()。
由于您使用的是C ++,类似这样的操作可能会更容易:
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更容易。 您可以使用unique_ptr
避免显式调用EVP_CIPHER_CTX_free
的函数。 请参阅EVP对称加密和解密| OpenSSL Wiki上的C ++程序 , 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)>;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.