基于Openssl的RSA加密解密文本

  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的字符串格式,否则也是没办法解密成功的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值