一、RSA是一种非对称加密算法,一般在数据加密的过程中会使用公钥加密,私钥解密,在签名生成和验证过程中会使用私钥加密,公钥解密。
二、使用openssl生成公钥和私钥
1、生成私钥,保存在文件rsa_private_key.pem里面
openssl genrsa -out rsa_private_key.pem 1024
2、通过私钥生成公钥,保存在文件rsa_private_key.pem里面
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
三、openssl公钥加密,私钥解密(私钥和公钥通过文件传进去),这里有一个注意点是在通过私钥解密的读取私钥信息时候使用的是PEM_read_bio_RSAPrivateKey,但是通过公钥加密读取公钥信息的时候使用的是PEM_read_bio_RSA_PUBKEY,而不是PEM_read_bio_RSAPublicKey。
// 通过公钥文件加密
std::vector<char> EncryptByPubkeyFile(const std::string& message,
const std::string& pub_filename) {
BIO* in = BIO_new(BIO_s_file());
if (in == NULL) {
std::cout << "BIO_new failed" << std::endl;
return std::vector<char>();
}
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 std::vector<char>();
}
int size = RSA_size(rsa);
std::vector<char> encrypt_data;
encrypt_data.resize(size);
int ret = RSA_public_encrypt(
message.length(), (unsigned char*)message.c_str(),
(unsigned char*)encrypt_data.data(), rsa, RSA_PKCS1_PADDING);
RSA_free(rsa);
if (ret == -1) {
std::cout << "RSA_public_encrypt failed" << std::endl;
return std::vector<char>();
}
return encrypt_data;
}
// 通过私钥文件解密
std::string DecryptByPrikeyFile(char* cipher, uint32_t len,
const std::string& pri_file) {
BIO* in = BIO_new(BIO_s_file());
if (in == NULL) {
std::cout << "BIO_new failed" << std::endl;
return "";
}
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 "";
}
int size = RSA_size(rsa);
std::vector<char> data;
data.resize(size);
int ret = RSA_private_decrypt(len, (unsigned char*)cipher,
(unsigned char*)data.data(), rsa,
RSA_PKCS1_PADDING);
RSA_free(rsa);
if (ret == -1) {
std::cout << "RSA_private_decrypt failed" << std::endl;
return "";
}
std::string decrypt_data(data.begin(), data.end());
return decrypt_data;
}
四、openssl公钥加密,私钥解密(私钥和公钥通过字符串传进去)
// 通过公钥字符串进行加密
std::vector<char> EncryptByPubkeyString(const std::string& message,
const std::string& pubkey) {
BIO* in = BIO_new_mem_buf((void*)pubkey.c_str(), -1);
if (in == NULL) {
std::cout << "BIO_new_mem_buf failed" << std::endl;
return std::vector<char>();
}
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 std::vector<char>();
}
int size = RSA_size(rsa);
std::vector<char> encrypt_data;
encrypt_data.resize(size);
int ret = RSA_public_encrypt(
message.length(), (unsigned char*)message.c_str(),
(unsigned char*)encrypt_data.data(), rsa, RSA_PKCS1_PADDING);
RSA_free(rsa);
if (ret == -1) {
std::cout << "RSA_public_encrypt failed" << std::endl;
return std::vector<char>();
}
return encrypt_data;
}
// 通过私钥字符串进行解密
std::string DecryptByPrikeyString(char* cipher, uint32_t len,
const std::string prikey) {
BIO* in = BIO_new_mem_buf((void*)prikey.c_str(), -1);
if (in == NULL) {
std::cout << "BIO_new_mem_buf failed" << std::endl;
return "";
}
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 "";
}
int size = RSA_size(rsa);
std::vector<char> data;
data.resize(size);
int ret = RSA_private_decrypt(len, (unsigned char*)cipher,
(unsigned char*)data.data(), rsa,
RSA_PKCS1_PADDING);
RSA_free(rsa);
if (ret == -1) {
std::cout << "RSA_private_decrypt failed" << std::endl;
return "";
}
std::string decrypt_data(data.begin(), data.end());
return decrypt_data;
}
五、openssl私钥加密,公钥解密(私钥和公钥通过文件传进去),一般用来生成和验证签名
// 通过私钥文件加密
std::vector<char> EncryptByPrikeyFile(const std::string& message,
const std::string& pri_file) {
BIO* in = BIO_new(BIO_s_file());
if (in == NULL) {
std::cout << "BIO_new failed" << std::endl;
return std::vector<char>();
}
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 std::vector<char>();
}
int size = RSA_size(rsa);
std::vector<char> encrypt_data;
encrypt_data.resize(size);
int ret = RSA_private_encrypt(
message.length(), (unsigned char*)message.c_str(),
(unsigned char*)encrypt_data.data(), rsa, RSA_PKCS1_PADDING);
RSA_free(rsa);
if (ret == -1) {
std::cout << "RSA_private_encrypt failed" << std::endl;
return std::vector<char>();
}
return encrypt_data;
}
// 通过公钥文件解密
std::string DecryptByPubkeyFile(char* cipher, uint32_t len,
const std::string& pub_filename) {
BIO* in = BIO_new(BIO_s_file());
if (in == NULL) {
std::cout << "BIO_new failed" << std::endl;
return "";
}
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 "";
}
int size = RSA_size(rsa);
std::vector<char> data;
data.resize(size);
int ret =
RSA_public_decrypt(len, (unsigned char*)cipher,
(unsigned char*)data.data(), rsa, RSA_PKCS1_PADDING);
RSA_free(rsa);
if (ret == -1) {
std::cout << "RSA_public_decrypt failed" << std::endl;
return "";
}
std::string decrypt_data(data.begin(), data.end());
return decrypt_data;
}
六、openssl私钥加密,公钥解密(私钥和公钥通过字符串传进去),一般用来生成和验证签名
// 通过私钥字符串加密
std::vector<char> EncryptByPrikeyString(const std::string& message,
const std::string& prikey) {
BIO* in = BIO_new_mem_buf((void*)prikey.c_str(), -1);
if (in == NULL) {
std::cout << "BIO_new_mem_buf failed" << std::endl;
return std::vector<char>();
}
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 std::vector<char>();
}
int size = RSA_size(rsa);
std::vector<char> encrypt_data;
encrypt_data.resize(size);
int ret = RSA_private_encrypt(
message.length(), (unsigned char*)message.c_str(),
(unsigned char*)encrypt_data.data(), rsa, RSA_PKCS1_PADDING);
RSA_free(rsa);
if (ret == -1) {
std::cout << "RSA_private_encrypt failed" << std::endl;
return std::vector<char>();
}
return encrypt_data;
}
// 通过公钥字符串解密
std::string DecryptByPubkeyString(char* cipher, uint32_t len,
const std::string& pubkey) {
BIO* in = BIO_new_mem_buf((void*)pubkey.c_str(), -1);
if (in == NULL) {
std::cout << "BIO_new_mem_buf failed" << std::endl;
return "";
}
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 "";
}
int size = RSA_size(rsa);
std::vector<char> data;
data.resize(size);
int ret =
RSA_public_decrypt(len, (unsigned char*)cipher,
(unsigned char*)data.data(), rsa, RSA_PKCS1_PADDING);
RSA_free(rsa);
if (ret == -1) {
std::cout << "RSA_public_decrypt failed" << std::endl;
return "";
}
std::string decrypt_data(data.begin(), data.end());
return decrypt_data;
}
七、openssl私钥生成签名,公钥验证签名(私钥和公钥通过文件传进去),这里传进去的message是一个文件的md5值,所以在RSA_sign函数和RSA_verify函数的第一个参数使用NID_md5
// 通过私钥文件生成签名
std::vector<char> GenerateRsaSignByFile(const std::string& message,
const std::string& pri_filename) {
OpenSSL_add_all_algorithms();
BIO* in = BIO_new(BIO_s_file());
if (in == NULL) {
std::cout << "BIO_new failed" << std::endl;
return std::vector<char>();
}
BIO_read_filename(in, pri_filename.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 std::vector<char>();
}
unsigned int size = RSA_size(rsa);
std::vector<char> sign;
sign.resize(size);
int ret =
RSA_sign(NID_md5, (const unsigned char*)message.c_str(),
message.length(), (unsigned char*)sign.data(), &size, rsa);
RSA_free(rsa);
if (ret != 1) {
std::cout << "RSA_sign failed" << std::endl;
return std::vector<char>();
}
return sign;
}
// 通过公钥文件验证签名
bool VerifyRsaSignByFile(char* sign, uint32_t sign_len,
const std::string& pub_filename,
const std::string& verify_str) {
OpenSSL_add_all_algorithms();
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);
if (rsa == NULL) {
std::cout << "PEM_read_bio_RSA_PUBKEY failed" << std::endl;
return false;
}
BIO_free(in);
int ret =
RSA_verify(NID_md5, (const unsigned char*)verify_str.c_str(),
verify_str.length(), (unsigned char*)sign, sign_len, rsa);
RSA_free(rsa);
if (ret != 1) {
std::cout << "RSA_verify failed" << std::endl;
return false;
}
return true;
}
八、openssl私钥生成签名,公钥验证签名(私钥和公钥通过字符串传进去)
// 通过私钥字符串生成签名
std::vector<char> GenerateRsaSignByString(const std::string& message,
const std::string& prikey) {
OpenSSL_add_all_algorithms();
BIO* in = BIO_new_mem_buf((void*)prikey.c_str(), -1);
if (in == NULL) {
std::cout << "BIO_new_mem_buf failed" << std::endl;
return std::vector<char>();
}
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 std::vector<char>();
}
unsigned int size = RSA_size(rsa);
std::vector<char> sign;
sign.resize(size);
int ret =
RSA_sign(NID_md5, (const unsigned char*)message.c_str(),
message.length(), (unsigned char*)sign.data(), &size, rsa);
RSA_free(rsa);
if (ret != 1) {
std::cout << "RSA_sign failed" << std::endl;
return std::vector<char>();
}
return sign;
}
// 通过公钥字符串验证签名
bool VerifyRsaSignByString(char* sign, uint32_t sign_len,
const std::string& pubkey,
const std::string& verify_str) {
BIO* in = BIO_new_mem_buf((void*)pubkey.c_str(), -1);
if (in == NULL) {
std::cout << "BIO_new_mem_buf failed" << std::endl;
return false;
}
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 ret =
RSA_verify(NID_md5, (const unsigned char*)verify_str.c_str(),
verify_str.length(), (unsigned char*)sign, sign_len, rsa);
RSA_free(rsa);
if (ret != 1) {
std::cout << "RSA_verify failed" << std::endl;
return false;
}
return true;
}