windows中使用c++通过openssl实现rsa加密的文章非常多,但是真正能用的没有几个,大部分都是linux版本的,而且代码不全、版本老旧、有BUG无法调试等,今天给大家带来一个完全可以的示例,希望对大家有所帮助。
效果图
main.cpp文件
/*
测试openssl版本为:Win32OpenSSL-1_1_0i
调试本源码前,必须先安装openssl
并且,将openssl所在的目录添加到编译器里面,如:C:\OpenSSL-Win32\include
连接器要添加:C:\OpenSSL-Win32\lib\libcrypto.lib
windows安装版openssl可以在这里下载:https://oomake.com/download/openssl
*/
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <base64.h>
#include <rsas.h>
using namespace std;
int main(void)
{
/*私钥是这样的,换行符被换成了\n
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCAhDZFe6UuxD2V2Gjf0HSlCxSWR+92+v9NG+B3sXfjS/uzcSZi
XeuyaFmTLB6QeCKA5Snou8uZyMNE3Bvdk1So1DPHHLajsHpERRNXiEVdxd60xEEM
/d/uqtey1napFiTNNStIjIcKb0+8S5Sy4GOsGrscAgRx3wYCAjF6QSqtOQIDAQAB
AoGAKPq/mXlbSyXNI3ZdvpxoTWZSmrb2b0CK3uoYMeJ3gZVtfaMDY9NiAEIQ6gJj
/pooGmS4b9tOCUwAo/jxs74yfKctL3HCoQcBfhAyGiyblby+oJ+i4zw8Sxlzjnp7
yBDZ2lRdDzLEYrab4e6UKTh6YTPNr2nI81JbIxghiA656lcCQQCCjmomitVvOpNm
a3Nnkh3fEl4tRaZNorY202oXJfO2W7EJfZbJg95HUJqC6mG3o0uOcCr7izQw9N0g
cBhJbO37AkEA/AALVSWEjKrWR57HTN8Z8jklkSzeiZVD5efT4ReabyeQQ4ZmoHpU
woOi8e3fo+7NrvTNE8XfBkT4LWY2wHMvWwJAOT42PsX6xTU6sdqFFDFV1ZwZHOKA
A2RHXoyd5J5oWFmlqxKczah7CmvGA4a+56S6mS6HOhmT/a8vUWy0yWTwhwJAZCuU
VaVTOiNSiCeqa3kntCxZLYsbbq9BzSrJA2nBfrvIUb8kHlhiRuvSor5+rohnhEtV
Fa4LCE/0Iv/FddyTjwJAWAUw9vXkEiUhGY9DoPlHynSaaGwpHzgDAPk9meW0AzCy
WB6kxSQIQIrifhQI3aTqbOjkqFW0O9uT9zLHvVzJ0Q==
-----END RSA PRIVATE KEY-----
*/
string pri = "-----BEGIN RSA PRIVATE KEY-----\nMIICWwIBAAKBgQCAhDZFe6UuxD2V2Gjf0HSlCxSWR+92+v9NG+B3sXfjS/uzcSZi\nXeuyaFmTLB6QeCKA5Snou8uZyMNE3Bvdk1So1DPHHLajsHpERRNXiEVdxd60xEEM\n/d/uqtey1napFiTNNStIjIcKb0+8S5Sy4GOsGrscAgRx3wYCAjF6QSqtOQIDAQAB\nAoGAKPq/mXlbSyXNI3ZdvpxoTWZSmrb2b0CK3uoYMeJ3gZVtfaMDY9NiAEIQ6gJj\n/pooGmS4b9tOCUwAo/jxs74yfKctL3HCoQcBfhAyGiyblby+oJ+i4zw8Sxlzjnp7\nyBDZ2lRdDzLEYrab4e6UKTh6YTPNr2nI81JbIxghiA656lcCQQCCjmomitVvOpNm\na3Nnkh3fEl4tRaZNorY202oXJfO2W7EJfZbJg95HUJqC6mG3o0uOcCr7izQw9N0g\ncBhJbO37AkEA/AALVSWEjKrWR57HTN8Z8jklkSzeiZVD5efT4ReabyeQQ4ZmoHpU\nwoOi8e3fo+7NrvTNE8XfBkT4LWY2wHMvWwJAOT42PsX6xTU6sdqFFDFV1ZwZHOKA\nA2RHXoyd5J5oWFmlqxKczah7CmvGA4a+56S6mS6HOhmT/a8vUWy0yWTwhwJAZCuU\nVaVTOiNSiCeqa3kntCxZLYsbbq9BzSrJA2nBfrvIUb8kHlhiRuvSor5+rohnhEtV\nFa4LCE/0Iv/FddyTjwJAWAUw9vXkEiUhGY9DoPlHynSaaGwpHzgDAPk9meW0AzCy\nWB6kxSQIQIrifhQI3aTqbOjkqFW0O9uT9zLHvVzJ0Q==\n-----END RSA PRIVATE KEY-----";
//原内容
string data = "你好中国!";
cout <<"\n\n私钥加密前:"<<data;
//私钥加密
data =rsa_pri_encrypt(data,pri);
data=base64_encode((const char *)(data.c_str()),data.length());
cout <<"\n\n私钥加密后:"<<data;
/*
公钥是这样的,换行符也换成了\n
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAhDZFe6UuxD2V2Gjf0HSlCxSW
R+92+v9NG+B3sXfjS/uzcSZiXeuyaFmTLB6QeCKA5Snou8uZyMNE3Bvdk1So1DPH
HLajsHpERRNXiEVdxd60xEEM/d/uqtey1napFiTNNStIjIcKb0+8S5Sy4GOsGrsc
AgRx3wYCAjF6QSqtOQIDAQAB
-----END PUBLIC KEY-----
*/
std::string pub="-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAhDZFe6UuxD2V2Gjf0HSlCxSW\nR+92+v9NG+B3sXfjS/uzcSZiXeuyaFmTLB6QeCKA5Snou8uZyMNE3Bvdk1So1DPH\nHLajsHpERRNXiEVdxd60xEEM/d/uqtey1napFiTNNStIjIcKb0+8S5Sy4GOsGrsc\nAgRx3wYCAjF6QSqtOQIDAQAB\n-----END PUBLIC KEY-----";
//base64解码
data=base64_decode(data);
//公钥解密
data=rsa_pub_decrypt(data,pub);
cout <<"\n\n公钥解密后:"<<data;
//公钥加密
data = rsa_pub_encrypt(data,pub);
//base64加密
data=base64_encode((const char *)(data.c_str()),data.length());
cout <<"\n\n公钥加密后:"<<data;
//base64解密
data=base64_decode(data);
//私钥解密后
data = rsa_pri_decrypt(data,pri);
cout <<"\n\n私钥解密后:"<<data;
return 0;
}
rsas.h文件
// 私钥加密
std::string rsa_pri_encrypt(const std::string &clearText, std::string &pubKey)
{
std::string strRet;
BIO *keybio = BIO_new_mem_buf((unsigned char *)pubKey.c_str(), -1);
RSA* rsa = RSA_new();
rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);
if (!rsa)
{
BIO_free_all(keybio);
return std::string("");
}
int len = RSA_size(rsa);
char *encryptedText = (char *)malloc(len + 1);
memset(encryptedText, 0, len + 1);
// 加密
int ret = RSA_private_encrypt(clearText.length(), (const unsigned char*)clearText.c_str(), (unsigned char*)encryptedText, rsa, RSA_PKCS1_PADDING);
if (ret >= 0)
strRet = std::string(encryptedText, ret);
// 释放内存
free(encryptedText);
BIO_free_all(keybio);
RSA_free(rsa);
return strRet;
}
// 公钥解密
std::string rsa_pub_decrypt(const std::string &clearText, std::string &pubKey)
{
std::string strRet;
BIO *keybio = BIO_new_mem_buf((unsigned char *)pubKey.c_str(), -1);
RSA* rsa = RSA_new();
//rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL);//这个失败,二脸萌壁...
rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL);
if (!rsa)
{
BIO_free_all(keybio);
return std::string("");
}
int len = RSA_size(rsa);
char *encryptedText = (char *)malloc(len + 1);
memset(encryptedText, 0, len + 1);
//解密
int ret = RSA_public_decrypt(clearText.length(), (const unsigned char*)clearText.c_str(), (unsigned char*)encryptedText, rsa, RSA_PKCS1_PADDING);
if (ret >= 0)
strRet = std::string(encryptedText, ret);
// 释放内存
free(encryptedText);
BIO_free_all(keybio);
RSA_free(rsa);
return strRet;
}
char *Base64Encode(const char* input, int length, bool with_new_line)
{
BIO* bmem = NULL;
BIO* b64 = NULL;
BUF_MEM* bptr = NULL;
b64 = BIO_new(BIO_f_base64());
if (!with_new_line)
{
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
}
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, input, length);
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
char * buff = (char *)malloc(bptr->length + 1);
memcpy(buff, bptr->data, bptr->length);
buff[bptr->length] = 0;
BIO_free_all(b64);
return buff;
}
char *Base64Decode(char* input, int length, bool with_new_line)
{
BIO * b64 = NULL;
BIO * bmem = NULL;
char * buffer = (char *)malloc(length);
memset(buffer, 0, length);
b64 = BIO_new(BIO_f_base64());
if (!with_new_line)
{
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
}
bmem = BIO_new_mem_buf(input, length);
bmem = BIO_push(b64, bmem);
BIO_read(bmem, buffer, length);
BIO_free_all(bmem);
return buffer;
}
// 公钥加密
std::string rsa_pub_encrypt(const std::string &clearText, std::string &pubKey)
{
std::string strRet;
BIO *keybio = BIO_new_mem_buf((unsigned char *)pubKey.c_str(), -1);
RSA* rsa = RSA_new();
//rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL);//这个失败,二脸萌壁..
rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL);
if (!rsa)
{
BIO_free_all(keybio);
return std::string("");
}
int len = RSA_size(rsa);
char *encryptedText = (char *)malloc(len + 1);
memset(encryptedText, 0, len + 1);
// 加密函数
int ret = RSA_public_encrypt(clearText.length(), (const unsigned char*)clearText.c_str(), (unsigned char*)encryptedText, rsa, RSA_PKCS1_PADDING);
if (ret >= 0)
strRet = std::string(encryptedText, ret);
// 释放内存
free(encryptedText);
BIO_free_all(keybio);
RSA_free(rsa);
return strRet;
}
// 私钥解密
std::string rsa_pri_decrypt(const std::string &cipherText, const std::string &priKey)
{
std::string strRet;
RSA *rsa = RSA_new();
BIO *keybio;
keybio = BIO_new_mem_buf((unsigned char *)priKey.c_str(), -1);
rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);
int len = RSA_size(rsa);
char *decryptedText = (char *)malloc(len + 1);
memset(decryptedText, 0, len + 1);
// 解密函数
int ret = RSA_private_decrypt(cipherText.length(), (const unsigned char*)cipherText.c_str(), (unsigned char*)decryptedText, rsa, RSA_PKCS1_PADDING);
if (ret >= 0)
strRet = std::string(decryptedText, ret);
// 释放内存
free(decryptedText);
BIO_free_all(keybio);
RSA_free(rsa);
return strRet;
}
base64.h文件
/*
使用方法
#include<stdio.h>
#include <string>
#include <iostream>
#include<stdio.h>
using namespace std;
int main() {
const std::string s = "123\nabc" ;
std::string encoded = base64_encode((const char*)(s.c_str()), s.length());
std::string decoded = base64_decode(encoded);
std::cout << "encoded: " << encoded << std::endl;
std::cout << "decoded: " << decoded << std::endl;
return 0;
}
*/
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
//A\nB 3
std::string base64_encode(char const* bytes_to_encode, int in_len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i < 4) ; i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
while((i++ < 3))
ret += '=';
}
return ret;
}
std::string base64_decode(std::string & encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
return ret;
}