天天看点

openssl库实现rsa加解密1、已知公钥密钥 进行加密 和解密

 rsa加密的public key格式有多种,常见的有两种,

一种密钥头为‘-----BEGIN RSA PUBLIC KEY-----’,

一种开头为‘-----BEGIN PUBLIC KEY-----’,

二者分别对应rsa的PKCS#1和PKCS#8格式。

使用openssl库加载rsa的公钥时,使用的函数也不同。以字符串公钥为例,对PKCS#1格式的密钥加载使用PEM_read_bio_RSAPublicKey()函数,对PKCS#8格式公钥的加载使用PEM_read_bio_RSA_PUBKEY()函数。

对于不那么熟悉rsa的同学,使用时注意区分者,可以减少不必要的麻烦。

// ---- rsa非对称加解密 ---- //  
#define KEY_LENGTH  512              // 密钥长度
#define PUB_KEY_FILE "pubkey.pem"    // 公钥路径
#define PRI_KEY_FILE "prikey.pem"    // 私钥路径
           

生成密钥对方法:

// 函数方法生成密钥对 
void rsa::generateRSAKey(std::string strKey[2])
{

	// 公私密钥对  
	size_t pri_len;
	size_t pub_len;
	char *pri_key = NULL;
	char *pub_key = NULL;

	// 生成密钥对  
	RSA *keypair = RSA_generate_key(KEY_LENGTH, RSA_3, NULL, NULL);

	BIO *pri = BIO_new(BIO_s_mem());
	BIO *pub = BIO_new(BIO_s_mem());

	PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);
	PEM_write_bio_RSAPublicKey(pub, keypair);

	// 获取长度  
	pri_len = BIO_pending(pri);
	pub_len = BIO_pending(pub);

	// 密钥对读取到字符串  
	pri_key = (char *)malloc(pri_len + 1);
	pub_key = (char *)malloc(pub_len + 1);

	BIO_read(pri, pri_key, pri_len);
	BIO_read(pub, pub_key, pub_len);

	pri_key[pri_len] = '\0';
	pub_key[pub_len] = '\0';

	// 存储密钥对  
	strKey[0] = pub_key;
	strKey[1] = pri_key;

	// 存储到磁盘(这种方式存储的是begin rsa public key/ begin rsa private key开头的)
	FILE *pubFile = fopen(PUB_KEY_FILE, "w");
	if (pubFile == NULL)
	{
		assert(false);
		return;
	}
	fputs(pub_key, pubFile);
	fclose(pubFile);

	FILE *priFile = fopen(PRI_KEY_FILE, "w");
	if (priFile == NULL)
	{
		assert(false);
		return;
	}
	fputs(pri_key, priFile);
	fclose(priFile);

	// 内存释放
	RSA_free(keypair);
	BIO_free_all(pub);
	BIO_free_all(pri);

	free(pri_key);
	free(pub_key);

}
           

1、已知公钥密钥 进行加密 和解密

 加载公钥

#include <openssl/pem.h>
#include <openssl/err.h>

RSA* rsa::CreatePubKey()
{
	RSA*pPubKey_ = NULL;
	BIO* bp = NULL;
	std::string strPublicKey = "-----BEGIN RSA PUBLIC KEY-----\n\
MEYCQQDtWr6MU1o9GQdepJMdrRJsDyA9/ENMNxKd5+Vja794dJGQF4rPEY/1jjUZ\n\
NrDpY8z3r+2zc9BoKlc1oVs+0Ri7AgED\n\
-----END RSA PUBLIC KEY-----\n";

	char *chPublicKey = const_cast<char *>(strPublicKey.c_str());
	if ((bp = BIO_new_mem_buf(chPublicKey, -1)) == NULL)
	{
		printf("BIO_new_mem_buf failed!\n");
		return pPubKey_;
	}
	//PEM_read_bio_RSAPublicKey
	pPubKey_ = PEM_read_bio_RSAPublicKey(bp, NULL, NULL, NULL);

	if (NULL == pPubKey_)
	{
		ERR_load_crypto_strings();
		char errBuf[512];
		ERR_error_string_n(ERR_get_error(), errBuf, sizeof(errBuf));
		printf("load public key failed[%s]\n", errBuf);
		return pPubKey_;
	}
	BIO_free_all(bp);

	return pPubKey_;
}
           

 加载密钥

RSA* rsa::CreatePriKey()
{
	RSA*pPubKey_ = NULL;
	BIO* bp = NULL;
	std::string strPublicKey = "-----BEGIN RSA PRIVATE KEY-----\n\
MIIBOgIBAAJBAO1avoxTWj0ZB16kkx2tEmwPID38Q0w3Ep3n5WNrv3h0kZAXis8R\n\
j/WONRk2sOljzPev7bNz0GgqVzWhWz7RGLsCAQMCQQCePH8IN5F+EK+UbbdpHgxI\n\
ChV+qCzdegxpRUOXnSpQTG2vcBaQlHDWHUurJCBECokOsDWZhXtMOI5ruPhMHEoL\n\
AiEA+V181QCm02k1S2UhLQfZ6spLi7NUP+J5vvx4GBJ7VKMCIQDzq3KT9YwTSyz4\n\
M19Te3oUl1wRmddXk1vCl5POuitVCQIhAKY+UzirGeJGI4eYwMiv5pyG3QfM4tVB\n\
pn9S+rq2/OMXAiEAonJMYqOyt4dzUCI/jPz8Dbo9YRE6OmI9LGUNNHwc41sCIA3l\n\
XdHvymRjRzXXSlf1IvW7QSEwhYO0ifGXsrTd3t5d\n\
-----END RSA PRIVATE KEY-----\n";

	char *chPublicKey = const_cast<char *>(strPublicKey.c_str());
	if ((bp = BIO_new_mem_buf(chPublicKey, -1)) == NULL)
	{
		printf("BIO_new_mem_buf failed!\n");
		return pPubKey_;
	}

	pPubKey_ = PEM_read_bio_RSAPrivateKey(bp, NULL, NULL, NULL);
	
	if (NULL == pPubKey_)
	{
		ERR_load_crypto_strings();
		char errBuf[512];
		ERR_error_string_n(ERR_get_error(), errBuf, sizeof(errBuf));
		printf("load public key failed[%s]\n", errBuf);
		return pPubKey_;
	}
	BIO_free_all(bp);

	return pPubKey_;
}
           

公钥加密:

// 公钥加密  
std::string rsa::rsa_pub_encrypt(const std::string &clearText)
{
	std::string strRet;
	
	RSA* rsa = CreatePubKey();
	
	int len = RSA_size(rsa);
	//int len = 1028;
	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::rsa_pri_decrypt(const std::string &cipherText)
{
	std::string strRet;
	RSA* rsa = CreatePriKey();

	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;

}
           

 2、从文件pubkey.pem 和prikey.pem 读取公钥和密钥

公钥加密: 

// 公钥加密  
std::string rsa::rsa_pub_encrypt(const std::string &clearText, std::string &pubKey)
{
	
	std::string strRet;
  	BIO * key = NULL;
  	RSA * rsa = NULL;
  	key = BIO_new(BIO_s_file());
  	BIO_read_filename(key, PUB_KEY_FILE);
  	rsa = PEM_read_bio_RSAPublicKey(key, NULL, NULL, NULL);
  	int len = RSA_size(rsa);
  	char *decryptedText = (char *)malloc(len + 1);
  	memset(decryptedText, 0, len + 1);
  
  	int lenf = clearText.length();
  
  	// 加密函数  
  	int ret = RSA_public_encrypt(lenf, (const unsigned char*)clearText.c_str(), (unsigned char*)decryptedText, rsa, RSA_PKCS1_OAEP_PADDING);
  	if (ret >= 0)
  		strRet = std::string(decryptedText, ret);
  
  	// 释放内存  
  	free(decryptedText);
  	BIO_free_all(key);
  	RSA_free(rsa);
  
  	return strRet;
	//方式二
 	/*std::string strRet;
 	RSA *rsa;
 
 	BIO * key = NULL;
 	FILE *fp;
 	if ((fp = fopen(PUB_KEY_FILE, "r")) == NULL) {
 		return "";
 	}
 
 	rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL);
 	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(key);
 	RSA_free(rsa);
 
 	return strRet;*/
}
           

私钥解密:

// 私钥解密  
std::string rsa::rsa_pri_decrypt(const std::string &cipherText, const std::string &priKey)
{
	
	//方式一
 	std::string strRet;
 	BIO * key = NULL;
 	RSA * rsa = NULL;
 	key = BIO_new(BIO_s_file());
 	BIO_read_filename(key, PRI_KEY_FILE);
 	rsa = PEM_read_bio_RSAPrivateKey(key, NULL, NULL, NULL);
 	int len = RSA_size(rsa);
 	char *decryptedText = (char *)malloc(len + 1);
 	memset(decryptedText, 0, len + 1);
 
  	// 解密函数  
 	int lenf = cipherText.length();
 	int ret = RSA_private_decrypt(lenf, (const unsigned char*)cipherText.c_str(), (unsigned char*)decryptedText, rsa, RSA_PKCS1_OAEP_PADDING);
 	if (ret >= 0)
 		strRet = std::string(decryptedText, ret);
/
 	// 释放内存  
 	free(decryptedText);
 	BIO_free_all(key);
 	RSA_free(rsa);
 
 	return strRet;

/* 	std::string strRet;
 	BIO * key = NULL;
 	RSA * rsa = NULL;
 	key = BIO_new(BIO_s_file());
 	BIO_read_filename(key, PUB_KEY_FILE);
 	rsa = PEM_read_bio_RSAPublicKey(key, NULL, NULL, NULL);
 	int len = RSA_size(rsa);
 	char *decryptedText = (char *)malloc(len + 1);
 	memset(decryptedText, 0, len + 1);
 
 	
 	// 解密函数  
 	int ret = RSA_public_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(key);
 	RSA_free(rsa);
  	return strRet;*/
}