RSA加密解密的小伙伴自己,出门左转自行百度谷歌去。要注意的是公钥加密过的数据,对应的私钥才能解密,反之私钥加密过的数据也只有对应的公钥才能解密。
#pragma once
#ifndef ENCRYPTDEMO_CRSA_H
#define ENCRYPTDEMO_CRSA_H
#include <openssl/rsa.h>
#include <string>
class CRSA
{
public:
static std::string encrypt_RSA_by_public_key(std::string& publicKey,const std::string& data);
static std::string decrypt_RSA_by_public_key(std::string& publicKey,const std::string& data);
static std::string encrypt_RSA_by_private_key(std::string& privateKey, const std::string& data);
static std::string decrypt_RSA_by_private_key(std::string& privateKey, const std::string& data);
private:
static std::string create_private_key(std::string& pristr);
static std::string create_public_key(std::string& pubstr);
static RSA* create_RSA(unsigned char* key, bool pub);
};
#endif //ENCRYPTDEMO_MYRSA_H
这里添加了连个函数create_private_key以及create_public_key,是用于转化Key的格式的,如果直接是输入公私钥的biao标准格式的时候,就直接调用加解密函数即可。(PS:这里踩过巨坑的,输入的如果是一长串的字符串一定要转成公私钥规定的准格式,否则无法运行的)
接下来是cpp文件:
#include "stdafx.h"
#include <cstddef>
#include <stdlib.h>
#include "openssl/bio.h"
#include "openssl/evp.h"
#include "openssl/rsa.h"
#include "openssl/pem.h"
#include <iostream>
#include "RSA.h"
/*
* 创建RSA指针
*/
RSA* CRSA::create_RSA(unsigned char* key, bool pub)
{
RSA* rsa = NULL;
BIO* keybio;
keybio = BIO_new_mem_buf(key, -1);
if (keybio == NULL)
{
printf("Failed to create key BIO\n");
return NULL;
}
if (pub)
{
rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL);
}
else
{
rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);
}
if (rsa == NULL)
{
printf("Failed to create RSA\n");
}
BIO_free_all(keybio);
return rsa;
}
/*
* 将公钥字符串安装RSA的字符串要求重新合成字符串
*/
std::string CRSA::create_public_key(std::string& pubstr)
{
if (pubstr.empty())
{
printf("public key read error\n");
return "public key read error\n";
}
int len = pubstr.length();
std::string tmp = pubstr;
for (int i = 64; i<len; i += 64)
{
if (tmp[i] != '\n')
{
tmp.insert(i, "\n");
}
i++;
}
tmp.insert(0, "-----BEGIN PUBLIC KEY-----\n");
tmp.append("\n-----END PUBLIC KEY-----\n");
return tmp;
}
/*
* 将私钥字符串安装RSA的字符串要求重新合成字符串
*/
std::string CRSA::create_private_key(std::string& pristr)
{
if (pristr.empty())
{
printf("private key read error\n");
return "private key read error\n";
}
int len = pristr.length();
std::string tmp = pristr;
for (int i = 64; i<len; i += 64)
{
if (tmp[i] != '\n')
{
tmp.insert(i, "\n");
}
i++;
}
tmp.insert(0, "-----BEGIN RSA PRIVATE KEY-----\n");
tmp.append("\n-----END RSA PRIVATE KEY-----\n");
return tmp;
}
/*
* 公钥加密
*/
std::string CRSA::encrypt_RSA_by_public_key(std::string& publicKey, const std::string& data)
{
std::string strRet;
///重组公钥字符串
publicKey = create_public_key(publicKey);
///创建RSA指针
RSA* rsa = create_RSA((unsigned char*)publicKey.c_str(), true);
int len = RSA_size(rsa);
char *encryptedText = (char *)malloc(len + 1);
memset(encryptedText, 0, len + 1);
int ret = RSA_public_encrypt(data.length(), (const unsigned char*)data.c_str(), (unsigned char*)encryptedText, rsa, RSA_PKCS1_PADDING);
/*outfile << "ret:" << ret << endl;
outfile << "encryptedText:" << encryptedText << endl;*/
if (ret >= 0)
strRet = std::string(encryptedText, ret);
free(encryptedText);
RSA_free(rsa);
return strRet;
}
/*
* 私钥解密
*/
std::string CRSA::decrypt_RSA_by_private_key(std::string& privateKey, const std::string& data)
{
std::string strRet;
///重组私钥字符串
privateKey = create_private_key(privateKey);
///创建RSA指针
RSA* rsa = create_RSA((unsigned char*)privateKey.c_str(), false);
int len = RSA_size(rsa);
char *decryptedText = (char *)malloc(len + 1);
memset(decryptedText, 0, len + 1);
int ret = RSA_private_decrypt(data.length(), (const unsigned char*)data.c_str(), (unsigned char*)decryptedText, rsa, RSA_PKCS1_PADDING);
if (ret >= 0)
strRet = std::string(decryptedText, ret);
free(decryptedText);
RSA_free(rsa);
return strRet;
}
/*
* 私钥加密
*/
std::string CRSA::encrypt_RSA_by_private_key(std::string& privateKey, const std::string& data)
{
std::string strRet;
///重组私钥字符串
privateKey = create_private_key(privateKey);
std::cout << privateKey << std::endl;
///创建RSA指针
RSA* rsa = create_RSA((unsigned char*)privateKey.c_str(), false);
int len = RSA_size(rsa);
char *encryptedText = (char *)malloc(len + 1);
memset(encryptedText, 0, len + 1);
int ret = RSA_private_encrypt(data.length(), (const unsigned char*)data.c_str(), (unsigned char*)encryptedText, rsa, RSA_PKCS1_PADDING);
if (ret >= 0)
strRet = std::string(encryptedText, ret);
free(encryptedText);
RSA_free(rsa);
return strRet;
}
/*
* 公钥解密
*/
std::string CRSA::decrypt_RSA_by_public_key(std::string& publicKey, const std::string& data)
{
std::string strRet;
///重组公钥字符串
publicKey = create_public_key(publicKey);
///创建RSA指针
RSA* rsa = create_RSA((unsigned char*)publicKey.c_str(), true);
int len = RSA_size(rsa);
char *decryptedText = (char *)malloc(len + 1);
memset(decryptedText, 0, len + 1);
int ret = RSA_public_decrypt(data.length(), (const unsigned char*)data.c_str(), (unsigned char*)decryptedText, rsa, RSA_PKCS1_PADDING);
if (ret >= 0)
strRet = std::string(decryptedText, ret);
free(decryptedText);
RSA_free(rsa);
return strRet;
}
最后要注意:加密后得到的数据是不识别的Base64的字符串格式,要转格式才能显示出来,解密前也要将密文转成Base64的字符串格式,否则也是没办法解密成功的。