1. 程式人生 > >使用openssl進行RSA加密解密

使用openssl進行RSA加密解密

原文:http://blog.csdn.net/zzj806683450/article/details/17426193

我使用openssl 1.0.1e,過程中遇到一些問題。

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>

#include <openssl/rsa.h>  
#include<openssl/pem.h>  
#include<openssl/err.h>  
#include <openssl/bio.h>  
#include <fstream>  
#include <iostream>  
#include <string>  
using namespace std;  
#pragma comment(lib, "libeay32.lib")  
#pragma comment(lib, "ssleay32.lib")  

#define PRIVATE_KEY_FILE	"private.pem"
#define PUBLIC_KEY_FILE		"public.pem"

const static char* pszPublicKey = "-----BEGIN RSA PUBLIC KEY-----\n"
	"MIGJAoGBAK7mh7RSMtisKLn+Jfkq9AUlOHqUe4zjTLVC89k+sPux5ZMr9ndtjzdx\n"
	"8bCcSfCQtemKrR2LY4lRr5cZs3jgwaBbHS2SdCezUuNUdrEEsfWX8BlK13G8djFm\n"
	"mYZqKeQFnUrKZn+uA0A4nIGPRFKB2fKfBjh4Y5qN2IoyV9Y0e8HHAgMBAAE=\n"
	"-----END RSA PUBLIC KEY-----";
const static char* pszPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\n"
	"MIICXQIBAAKBgQCu5oe0UjLYrCi5/iX5KvQFJTh6lHuM40y1QvPZPrD7seWTK/Z3\n"
	"bY83cfGwnEnwkLXpiq0di2OJUa+XGbN44MGgWx0tknQns1LjVHaxBLH1l/AZStdx\n"
	"vHYxZpmGainkBZ1KymZ/rgNAOJyBj0RSgdnynwY4eGOajdiKMlfWNHvBxwIDAQAB\n"
	"AoGASbqenFJGYvZ4GKfdhCMqSPz+yRXM24B6NrMprnvyCbhdiePvezrxM7NR6lyI\n"
	"AuRN+0xdW+YFqL6Joc3QzXUZyffUtJ0I25J/r2UvpEY0GaH7JJKdfpE4YycQRkRc\n"
	"gGt9YbcIjU4w0IpoIMH5G809ab6gTUxO1AwaAH1BovGt0vkCQQDfZxGT/AF+yCud\n"
	"8YTqfEWRNgSOWxyyXefSCGh3x6HDo5uybOrVVpUOcB6WVRoj3mgUEtzAz4+jqe30\n"
	"Bbknx8tFAkEAyGu5g6PjylakW1unrd1c3qlXR6C1wSHpYfpqhuDdw8nqD35pIWBy\n"
	"UF9ELfd6gbh/6fnfiKcQJEDlgnkkKchjmwJALmvKWUe6P8/0UEOJbPgZtIzW8YW5\n"
	"Ns8QhrI8kvcmg/KRPcgoG+B75J4jnPVeEyn50oIA4QfAPy/mRBiUWtHHSQJBALZb\n"
	"PeqG/kYmW1k8pe7OUSfPULi9g2J85ordfHvIsj7owuziCenyhVCXvcNNP8w0AT70\n"
	"uezuhQNXgPwcGUljKS0CQQDcKBgUE8PoT4Sic6WGvx+2S+gdXplNoZWhY/1p05fp\n"
	"ddSkrRUiaC7CUGYilG2ea1r+7VWVWsSwS8vSceIBxBeV\n"
	"-----END RSA PRIVATE KEY-----";

void generateKey() 
{  
	/* 生成公鑰 */  
	RSA* rsa = RSA_generate_key( 1024, RSA_F4, NULL, NULL);  
	BIO *bp = BIO_new( BIO_s_file() );  
	BIO_write_filename( bp, PUBLIC_KEY_FILE );
	PEM_write_bio_RSAPublicKey(bp, rsa);  
	BIO_free_all( bp );  

	/* 生成私鑰 */  
	bp = BIO_new( BIO_s_file() );  
	BIO_write_filename( bp, PRIVATE_KEY_FILE );
	PEM_write_bio_RSAPrivateKey(bp, rsa, NULL, NULL, 0, NULL, NULL);  
	CRYPTO_cleanup_all_ex_data();
	BIO_free_all( bp );  
	RSA_free(rsa);  
}

std::string bio_read_privateKey(string data) 
{  
	OpenSSL_add_all_algorithms();  
	BIO* bp = BIO_new( BIO_s_file() );  
	BIO_read_filename( bp, PRIVATE_KEY_FILE );  

	RSA* rsaK;
	rsaK = PEM_read_bio_RSAPrivateKey( bp, NULL, NULL, NULL );  
	if (NULL == rsaK) {
		printf("read key file fail!\n");  
#if 0
		unsigned long ulErr = ERR_get_error();
		char szErrMsg[1024] = {0};
		char *pTmp = NULL;
		pTmp = ERR_error_string(ulErr,szErrMsg); 
		printf("%s\n", szErrMsg);
		system("pause");
#endif
	}else{  
		//printf("read success!\n");  
	}  

	int nLen = RSA_size(rsaK);  
	char *pEncode = new char[nLen + 1];  
	int ret = RSA_private_decrypt(data.length(),(const unsigned char*)data.c_str(),(unsigned char *)pEncode,rsaK,RSA_PKCS1_PADDING);  
	std::string strRet;  
	if (ret >= 0) {  
		strRet = std::string(pEncode, ret);
	}  

	delete[] pEncode;  
	CRYPTO_cleanup_all_ex_data();  
	BIO_free_all( bp );  
	RSA_free(rsaK);  
	return strRet;  
}

std::string bio_read_privateKey2(string data) 
{
	OpenSSL_add_all_algorithms();  
	BIO* bp = BIO_new( BIO_s_mem() );  
	BIO_puts(bp, pszPrivateKey);

	RSA* rsaK;
	rsaK = PEM_read_bio_RSAPrivateKey( bp, NULL, NULL, NULL );  
	if (NULL == rsaK) {
		perror("read key file fail!");  
	}else{  
		//printf("read success!\n");  
	}  

	int nLen = RSA_size(rsaK);  
	char *pEncode = new char[nLen + 1];  
	int ret = RSA_private_decrypt(data.length(),(const unsigned char*)data.c_str(),(unsigned char *)pEncode,rsaK,RSA_PKCS1_PADDING);  
	std::string strRet;  
	if (ret >= 0) {  
		strRet = std::string(pEncode, ret);  
	}  

	delete[] pEncode;  
	CRYPTO_cleanup_all_ex_data();  
	BIO_free_all( bp );  
	RSA_free(rsaK);  
	return strRet;  
}

std::string bio_read_publicKey(string data)
{
	OpenSSL_add_all_algorithms();  
	BIO* bp = BIO_new( BIO_s_file() );  
	BIO_read_filename( bp, PUBLIC_KEY_FILE );
	RSA* rsaK = PEM_read_bio_RSAPublicKey( bp, NULL, NULL, NULL );  
	if (NULL == rsaK) {
		printf("read key file fail!");  
	}else{

	}  
	int nLen = RSA_size(rsaK);  
	char *pEncode = new char[nLen + 1];  
	int ret = RSA_public_encrypt(data.length(),(const unsigned char*)data.c_str(),  
		(unsigned char *)pEncode,rsaK,RSA_PKCS1_PADDING);  
	std::string strRet;  
	if (ret >= 0) {  
		strRet = std::string(pEncode, ret);
	}
	delete[] pEncode;  
	CRYPTO_cleanup_all_ex_data();  
	BIO_free_all( bp );  
	RSA_free(rsaK);  
	return strRet;  
}

std::string bio_read_publicKey2(string data)
{
	OpenSSL_add_all_algorithms();  
	BIO* bp = BIO_new( BIO_s_mem() );  
	BIO_puts(bp, pszPublicKey);
	RSA* rsaK = PEM_read_bio_RSAPublicKey( bp, NULL, NULL, NULL );  
	if (NULL == rsaK) {
		printf("read key file fail!\n");
#if 0
		unsigned long ulErr = ERR_get_error();
		char szErrMsg[1024] = {0};
		char *pTmp = NULL;
		pTmp = ERR_error_string(ulErr,szErrMsg); 
		printf("%s\n", szErrMsg);
		system("pause");
#endif
	}else{  
		
	}  
	int nLen = RSA_size(rsaK);  
	char *pEncode = new char[nLen + 1];  
	int ret = RSA_public_encrypt(data.length(),(const unsigned char*)data.c_str(),  
		(unsigned char *)pEncode,rsaK,RSA_PKCS1_PADDING);  
	std::string strRet;  
	if (ret >= 0) {  
		strRet = std::string(pEncode, ret);   
	}  
	delete[] pEncode;  
	CRYPTO_cleanup_all_ex_data();  
	BIO_free_all( bp );  
	RSA_free(rsaK);  
	return strRet;  
}  

void encryptFile(string inputfile,string outputfile)
{
	ifstream file(inputfile.c_str());  
	ofstream outfile(outputfile.c_str());  
	string tsum;  
	string ss;  
	while (getline(file,ss)) {  
		tsum.append(ss.append("\n"));  
	}  
	cout<<"徐加密內容:"<<tsum<<endl;  
	string mw = bio_read_publicKey(tsum);  
	cout<<mw<<endl;  
	outfile<<mw;  
	outfile.flush();  
	outfile.close();  
	file.close();  
}  

void decryptFile(string inputfile,string outputfile)
{
	ifstream file(inputfile.c_str());  
	ofstream outfile(outputfile.c_str());  
	std::string tsum,ss;  
	while (getline(file,ss)) {  
		tsum.append(ss);  
	}  
	std::string cw = bio_read_privateKey(tsum);  
	cout<<"恢復明文:"<<cw;  
	outfile<<cw;  
	outfile.flush();  
	outfile.close();  
	file.close();  
}  

int _tmain(int argc, _TCHAR* argv[])
{
	ERR_load_ERR_strings();
	ERR_load_crypto_strings(); 

	char *str = "第一步,首先需要在openssl官網下載openssl包http://www.openssl.org/source/;\n第二步,自己查資料去!";  
    //system("openssl genrsa -out private.key 1024");  
    //generateKey();
    printf("原文:\n%s\n\n",str);  
    std::string m = bio_read_publicKey2(str);  
    printf("密文:\n%s\n\n",m.c_str());  
    string miwen = m;  
    std::string c = bio_read_privateKey2(miwen);  
    printf("解密後:\n%s\n\n",c.c_str());  
      
#if 0
    encryptFile("d:/before.txt","f:/my.txt");  
    decryptFile("f:/my.txt","f:/jiemihou.txt");
#endif

	ERR_free_strings();

	system("pause");
	return 0;
}