rsa_private_decrypt返回-1,错误0x0306B067
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了rsa_private_decrypt返回-1,错误0x0306B067相关的知识,希望对你有一定的参考价值。
我想在C ++中使用OpenSSL测试RSA密钥对。我加密文本并立即解密。加密成功完成,但解密始终返回-1。错误号是:
0306B067:lib(3):func(107):reason(103)
我找不到原因......代码是:
char* text = "hello!!!";
unsigned char * cipher ;
unsigned char * decipher ;
int size = RSA_size(prvKey);
cipher = (unsigned char *)malloc(size);
decipher = (unsigned char *)malloc(size);
int cipherres = RSA_public_encrypt(size - 11/*strlen(text)*/,(unsigned char*)text,cipher,pubKey,RSA_PKCS1_PADDING);
int decipherres = RSA_private_decrypt(size,cipher,decipher,prvKey,RSA_PKCS1_PADDING);
if (decipherres == -1)
在使用RSA_generate_key_ex()
函数之前生成了RSA密钥对,它的密钥对在pubKey和prvKey中。
我不喜欢这一行的外观:
int cipherres = RSA_public_encrypt(size - 11 / strlen(text)/,...
您应该使用文本的长度,这似乎是您之前所做的。我不知道你从哪里得到11,但代码中的魔术数字味道不好。
尝试:
int cipherres = RSA_public_encrypt(strlen(text),...
另外,参考RSA_public_encrypt here的文档,以下行看起来错误:
int size = RSA_size(prvKey);
根据定义,prvKey和pubKey的大小是否相同?如果没有,请尝试使用公钥在加密前获取大小:
int size = RSA_size(pubKey);
然后,您可能需要将解密缓冲区的prvKey和malloc的大小分别调整到该大小。
您的程序有几个问题。其中一些是由@Resource指出的。因为你有这个标记为C ++,这里是C ++做这些事情的方法。它与你编写的基本程序相同,但很多问题都解决了。
答案还使用qazxsw poi进行RSA密钥对生成。
OpenSSL建议您使用EVP接口而不是How to generate RSA private key using OpenSSL?和RSA_public_encrypt
。另请参阅OpenSSL wiki上的RSA_private_decrypt
。
EVP Asymmetric Encryption and Decryption
该程序只需要库的加密部分。该程序是从OpenSSL 1.0.2源目录构建的,具有:
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/rsa.h>
#include <string>
#include <memory>
#include <sstream>
#include <iostream>
#include <stdexcept>
#include <cassert>
#define ASSERT assert
using BN_ptr = std::unique_ptr<BIGNUM, decltype(&::BN_free)>;
using RSA_ptr = std::unique_ptr<RSA, decltype(&::RSA_free)>;
int main(int argc, char* argv[])
{
////////////////////////////////////////////////////////////
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
////////////////////////////////////////////////////////////
RSA_ptr privKey(RSA_new(), ::RSA_free);
RSA_ptr pubKey(RSA_new(), ::RSA_free);
BN_ptr bn(BN_new(), ::BN_free);
int rc;
// Set exponent
rc = BN_set_word(bn.get(), RSA_F4);
ASSERT(rc == 1);
if (rc != 1)
{
std::ostringstream msg;
msg << "BN_set_word failed. Error 0x" << std::hex << ERR_get_error();
throw std::runtime_error(msg.str());
}
// Generate private key
rc = RSA_generate_key_ex(privKey.get(), 2048, bn.get(), NULL);
ASSERT(rc == 1);
if (rc != 1)
{
std::ostringstream msg;
msg << "RSA_generate_key_ex failed. Error 0x" << std::hex << ERR_get_error();
throw std::runtime_error(msg.str());
}
// Create a public key from private key
pubKey.reset(RSAPublicKey_dup(privKey.get()));
////////////////////////////////////////////////////////////
std::string text = "Yoda said, Do or do not. There is no try.";
std::string cipher, decipher;
int size = RSA_size(privKey.get());
ASSERT(size >= 0);
if (size < 0)
{
std::ostringstream msg;
msg << "RSA_size failed. Error 0x" << std::hex << ERR_get_error();
throw std::runtime_error(msg.str());
}
// 41 due to RSA_PKCS1_OAEP_PADDING
ASSERT(text.length() + 41 < size);
if (text.length() + 41 >= size)
{
std::ostringstream msg;
msg << "Plain text length is too long for modulus and padding";
throw std::runtime_error(msg.str());
}
// Resize to maximum size
cipher.resize(size);
decipher.resize(size);
rc = RSA_public_encrypt(text.length(),(unsigned char*)&text[0],
(unsigned char*)&cipher[0], pubKey.get(), RSA_PKCS1_OAEP_PADDING);
ASSERT(rc >= 0);
if (rc < 0)
{
std::ostringstream msg;
msg << "RSA_public_encrypt failed. Error 0x" << std::hex << ERR_get_error();
throw std::runtime_error(msg.str());
}
// Resize now that we know the size
cipher.resize(size);
rc = RSA_private_decrypt(cipher.length(), (unsigned char*)&cipher[0],
(unsigned char*)&decipher[0], privKey.get(), RSA_PKCS1_OAEP_PADDING);
ASSERT(rc >= 0);
if (rc < 0)
{
std::ostringstream msg;
msg << "RSA_private_decrypt failed. Error 0x" << std::hex << ERR_get_error();
throw std::runtime_error(msg.str());
}
std::cout << "Message: " << text << std::endl;
std::cout << "Recovered: " << decipher << std::endl;
return 0;
}
关于这个:
$ g++ -std=c++11 -DNDEBUG -I ./include test.cxx ./libcrypto.a -ldl -o test.exe
$ ./test.exe
Message: Yoda said, Do or do not. There is no try.
Recovered: Yoda said, Do or do not. There is no try.
尝试:
0306B067:lib(3):func(107):reason(103)
我的猜测是,$ openssl errstr 0306B067
error:0306B067:bignum routines:BN_div:div by zero
或pubKey
有问题。
以上是关于rsa_private_decrypt返回-1,错误0x0306B067的主要内容,如果未能解决你的问题,请参考以下文章