openssl私钥加密公钥解密demo
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <algorithm>
#include <iostream>
using namespace std;
bool Encrypt(std::vector<char>& origin_data,
const std::string& pri_file,
std::vector<char>& cipher_out) {
BIO* in = BIO_new(BIO_s_file());
if (in == NULL) {
std::cout << "BIO_new failed" << std::endl;
return false;
}
BIO_read_filename(in, pri_file.c_str());
RSA* rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL);
BIO_free(in);
if (rsa == NULL) {
std::cout << "PEM_read_bio_RSAPrivateKey failed" << std::endl;
return false;
}
int size = RSA_size(rsa);
int block_size = size;
while (origin_data.size() % block_size > 0) {
origin_data.push_back(0);
}
cipher_out.clear();
cout << origin_data.size() / block_size;
for (int i = 0; i < origin_data.size(); i += block_size) {
std::vector<char>::const_iterator first = origin_data.begin() + i;
std::vector<char>::const_iterator last = first + block_size;
std::vector<char> message(first, last);
std::vector<char> encryptdata;
encryptdata.resize(block_size);
int ret = RSA_private_encrypt(block_size, (unsigned char*)message.data(),
(unsigned char*)encryptdata.data(), rsa,
RSA_NO_PADDING);
if (ret == -1) {
RSA_free(rsa);
std::cout << "RSA_private_encrypt failed" << std::endl;
return false;
}
cipher_out.insert(cipher_out.end(), encryptdata.begin(), encryptdata.end());
}
std::cout << "cipher_out" << cipher_out.size() << std::endl;
RSA_free(rsa);
return true;
}
bool Decrypt(const std::vector<char>& ciphertext,
const std::string& pub_filename,
std::string& message_out) {
BIO* in = BIO_new(BIO_s_file());
if (in == NULL) {
std::cout << "BIO_new failed" << std::endl;
return false;
}
BIO_read_filename(in, pub_filename.c_str());
RSA* rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
BIO_free(in);
if (rsa == NULL) {
std::cout << "PEM_read_bio_RSA_PUBKEY failed" << std::endl;
return false;
}
int size = RSA_size(rsa);
int block_size = size;
while (ciphertext.size() % block_size != 0) {
std::cerr << "Unexcept data size: " << ciphertext.size() << std::endl;
return false;
}
std::vector<char> data;
for (int i = 0; i < ciphertext.size(); i += block_size) {
std::vector<char>::const_iterator first = ciphertext.begin() + i;
std::vector<char>::const_iterator last = first + block_size;
std::vector<char> cipher(first, last);
std::vector<char> message;
message.resize(block_size);
int ret =
RSA_public_decrypt(block_size, (unsigned char*)cipher.data(),
(unsigned char*)message.data(), rsa, RSA_NO_PADDING);
if (ret == -1) {
RSA_free(rsa);
std::cout << "RSA_public_decrypt failed" << std::endl;
return false;
}
data.insert(data.end(), message.begin(), message.end());
}
RSA_free(rsa);
message_out.clear();
message_out = data.data();
// erase the padding 0 in the string end
message_out.erase(std::remove(message_out.begin(), message_out.end(), 0),
message_out.end());
return true;
}