使用openssl进行RSA加密解密

时间:2021-02-06 18:29:00

原文: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;
}