OpenSSL C++ RSA 超长string 加密解密

最近公司为了dll的加密需要服务器生成授权证书文件,因此需要针对授权文件进行RSA加密。RSA的加密的长度是有要求的,因此对于超长的字符串要么采用新的加密方式:

1、AES针对授权证书加密 + RSA针对Key的加密(对称加密是不收到明文长度影响)

2、RSA超长明文分段加密的方式

这里就介绍RSA超长明文分段加密的简单步:

1、根据生成的RSA生成的长度来分割明文字段长度,加密次数 = 明文长度 / RSA加密字段长度 + 1

2、加密后的Base64字段拼接起来,再通过base64 to string 转成可见密文

直接上代码:

//rsa.h
//公钥加解密
static std::string encrypt_RSA_by_long_str_public_key(std::string publicKey, const std::string& data);
static std::string decrypt_RSA_by_long_str_public_key(std::string publicKey, const std::string& data);
//私钥加解密
static std::string encrypt_RSA_by_long_str_private_key(std::string privateKey, const std::string& data);
static std::string decrypt_RSA_by_long_str_private_key(std::string privateKey, const std::string& data);

Cpp代码:

/*
 * 公钥加密
 */
std::string CRSA::encrypt_RSA_by_long_str_public_key(std::string publicKey, const std::string& data)
{
	std::string strRet;
	///创建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 nClearDataLen = data.length();

	int pdBlock = len - 11;
	int nCount = (nClearDataLen / pdBlock) + 1;//分段次数
	unsigned char* pClearData = (unsigned char*)data.c_str();
    //分段加密
	for (int i = 0; i < nCount; i++)
	{
		int nSize = 0;
		pdBlock = (nClearDataLen > pdBlock) ? pdBlock : nClearDataLen;
		nSize = RSA_public_encrypt(pdBlock, (const unsigned char*)pClearData, (unsigned char*)decryptedText, rsa, RSA_PKCS1_PADDING);
		pClearData += pdBlock;
		nClearDataLen -= pdBlock;

		if (nSize >= 0)
		{
			strRet += std::string(decryptedText, nSize);
		}
	}

	// 释放内存
	delete decryptedText;
	RSA_free(rsa);
	return strRet;
}
/*
 * 公钥解密
 */
std::string CRSA::decrypt_RSA_by_long_str_public_key(std::string publicKey, const std::string& data)
{
	std::string strRet;
	///创建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 nClearDataLen = data.length();

	int pdBlock = len;
	int nCount = (nClearDataLen / pdBlock) + 1;//分段次数
	unsigned char* pClearData = (unsigned char*)data.c_str();
    //分段解密
	for (int i = 0; i < nCount; i++)
	{
		int nSize = 0;
		
		pdBlock = (nClearDataLen > pdBlock) ? pdBlock : nClearDataLen;
		nSize = RSA_public_decrypt(pdBlock, (const unsigned char*)pClearData, (unsigned char*)decryptedText, rsa, RSA_PKCS1_PADDING);
		pClearData += pdBlock;
		nClearDataLen -= pdBlock;

		if (nSize >= 0)
		{
			strRet += std::string(decryptedText, nSize);
		}
	}
    delete decryptedText;
	// 释放内存
	RSA_free(rsa);
	return strRet;
}

/*
 * 私钥加密
 */
std::string CRSA::encrypt_RSA_by_long_str_private_key(std::string privateKey, const std::string& data)
{
	std::string strRet;
	///创建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 nClearDataLen = data.length();

	int pdBlock = len - 11;
	int nCount = (nClearDataLen / pdBlock) + 1;//分段次数
	unsigned char* pClearData = (unsigned char*)data.c_str();
    //分段加密
	for (int i = 0; i < nCount; i++)
	{
		int nSize = 0;
		pdBlock = (nClearDataLen > pdBlock) ? pdBlock : nClearDataLen;
		nSize = RSA_private_encrypt(pdBlock, (const unsigned char*)pClearData, (unsigned char*)decryptedText, rsa, RSA_PKCS1_PADDING);
		pClearData += pdBlock;
		nClearDataLen -= pdBlock;

		if (nSize >= 0)
		{
			strRet += std::string(decryptedText, nSize);
		}
	}

	// 释放内存
	delete decryptedText;
	RSA_free(rsa);
	return strRet;
}
/*
 * 私钥解密
 */
std::string CRSA::decrypt_RSA_by_long_str_private_key(std::string privateKey, const std::string& data)
{
	std::string strRet;
	///创建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 nClearDataLen = data.length();
	int pdBlock = len;
	int nCount = (nClearDataLen / pdBlock) + 1;//分段次数
	unsigned char* pClearData = (unsigned char*)data.c_str();
    //分段解密
	for (int i = 0; i < nCount; i++)
	{
		int nSize = 0;
		
		pdBlock = (nClearDataLen > pdBlock) ? pdBlock : nClearDataLen;
		nSize = RSA_private_decrypt(pdBlock, (const unsigned char*)pClearData, (unsigned char*)decryptedText, rsa, RSA_PKCS1_PADDING);
		pClearData += pdBlock;
		nClearDataLen -= pdBlock;

		if (nSize >= 0)
		{
			strRet += std::string(decryptedText, nSize);
		}
	}
    delete decryptedText;
	// 释放内存
	RSA_free(rsa);
	return strRet;
}

 

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值