您的位置:首页 > 编程语言 > C语言/C++

OpenSSLRSA.cpp

2016-07-13 17:47 621 查看
#include "OpenSSLRSA.h"

#include <openssl/rsa.h>

#include <openssl/err.h>

#include <openssl/pem.h>

#include<fstream>

#include "../SrvUnit/ql_phone_public.h"

// 创建秘钥大小

const int RSA_KEY_BIT = 1024;

// RSA密文数据长度

const int RSA_DATA_LEN = 128;

COpenSSLRSA::COpenSSLRSA(void)

{
m_pRSAPub = NULL;
m_pRSAPri = NULL;
memset(m_sPriKeyPwd, 0, sizeof(m_sPriKeyPwd));
memset(m_sErrMsg, 0, sizeof(m_sErrMsg));

}

COpenSSLRSA::~COpenSSLRSA(void)

{
if(m_pRSAPub != NULL)
{
RSA_free(m_pRSAPub);
m_pRSAPub = NULL;
}

if(m_pRSAPri != NULL)
{
RSA_free(m_pRSAPri);
m_pRSAPri = NULL;
}

}

// 取得错误信息

void COpenSSLRSA::PrintErrMsg(int nRet, char* sFuncName)

{
ERR_load_crypto_strings();
char errBuf[512];
ERR_error_string_n(ERR_get_error(), errBuf, sizeof(errBuf));
sprintf(m_sErrMsg, "%s failed [ret = %d: %s]\n", sFuncName, nRet, errBuf);
printf(m_sErrMsg);

}

//RSA公钥加密

std::string COpenSSLRSA::EncodeRSAPubKeyData(bool bIsBase64)

{
unsigned char sOut[RSA_DATA_LEN] = {0};
int ret = RSA_public_encrypt(m_sText.length(), (const unsigned char*)m_sText.c_str(), sOut, m_pRSAPub, RSA_PKCS1_PADDING);
if (ret <= 0)
{
PrintErrMsg(ret, "EncodeRSAPubKeyData");
return "";
}

if (bIsBase64)
{

// 密文(乱码)转换为base64编码

unsigned char sBase64[RSA_KEY_BIT] = {0};

base64_encode(sOut, sizeof(sOut), sBase64);
m_sCryptText = string((char*)sBase64);
}
else
{
m_sCryptText = string((char*)sOut);
}

return m_sCryptText;

}

//RSA公钥解密

std::string COpenSSLRSA::DecodeRSAPubKeyData(bool bIsBase64)

{
unsigned char sBase64[RSA_KEY_BIT] = {0};
if (bIsBase64)
{
// base64编码密文转换为乱码密文
base64_decode((unsigned char*)m_sCryptText.c_str(), sBase64);
}
else
{
memcpy(sBase64, m_sCryptText.c_str(), m_sCryptText.size());
}

unsigned char sOut[RSA_KEY_BIT] = {0};
int ret = RSA_private_decrypt(RSA_DATA_LEN, sBase64, sOut, m_pRSAPri, RSA_PKCS1_PADDING);
if(ret <= 0)
{
PrintErrMsg(ret, "DecodeRSAPubKeyData");
return "";
}

CRYPTO_cleanup_all_ex_data();

m_sText = string((char*)sOut);
return m_sText;

}

//RSA私钥加密

std::string COpenSSLRSA::EncodeRSAPriKeyData(bool bIsBase64)

{
unsigned char sOut[RSA_DATA_LEN] = {0};
int ret = RSA_public_encrypt(m_sText.length(), (const unsigned char*)m_sText.c_str(), sOut, m_pRSAPub, RSA_PKCS1_PADDING);
if (ret <= 0)
{
PrintErrMsg(ret, "EncodeRSAPriKeyData");
return "";
}

if (bIsBase64)
{

// 密文(乱码)转换为base64编码

unsigned char sBase64[RSA_KEY_BIT] = {0};

base64_encode(sOut, sizeof(sOut), sBase64);
m_sCryptText = string((char*)sBase64);
}
else
{
m_sCryptText = string((char*)sOut);
}

return m_sCryptText;

}

//RSA私钥解密

std::string COpenSSLRSA::DecodeRSAPriKeyData(bool bIsBase64)

{
unsigned char sBase64[RSA_KEY_BIT] = {0};
if (bIsBase64)
{
// base64编码密文转换为乱码密文
base64_decode((unsigned char*)m_sCryptText.c_str(), sBase64);
}
else
{
memcpy(sBase64, m_sCryptText.c_str(), m_sCryptText.size());
}

unsigned char sOut[RSA_KEY_BIT] = {0};
int ret = RSA_private_decrypt(RSA_DATA_LEN, sBase64, sOut, m_pRSAPri, RSA_PKCS1_PADDING);
if(ret <= 0)
{
PrintErrMsg(ret, "DecodeRSAPriKeyData");
return "";
}

CRYPTO_cleanup_all_ex_data();

m_sText = string((char*)sOut);
return m_sText;

}

// 取得秘钥文件内容

//-----BEGIN PUBLIC KEY-----

//MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC84VjfOD9gJO6Qy3gXYrAJREEx

//vodi9kEi9PVtrJpT+m23mILcLLVMQ0HUvw56pV/0dSXWhUHaFxtDpjO8Y+sIMoyo

//jJ4ioXBmfik+fq3tcEMef+Tmtvwi9OvtY0VNuuMwFTVCrZgE5Zfh6QuJ0N56qcOm

//IPqr2LLMg0gcKVsrmwIDAQAB

//-----END PUBLIC KEY-----

void COpenSSLRSA::GetKeyFileContent(string filename, string& sKeyText)

{
sKeyText = "";

ifstream keyfile(filename.c_str());
string temp;
while(getline(keyfile, temp))
{
if(temp.substr(0, 5) == "-----")
continue;
if(temp.substr(0, 5) == "-----")
break;

sKeyText.append(temp);
temp = "";
}

}

// 创建秘钥对文件和秘钥对象

void COpenSSLRSA::BuildKey() 

{  
// 创建秘钥对
RSA* rsa = RSA_generate_key( 1024, RSA_F4, NULL, NULL);  

// 生成公钥对象
if(m_pRSAPub != NULL)
{
RSA_free(m_pRSAPub);
}
m_pRSAPub = RSAPublicKey_dup(rsa);

// 生成私钥对象
if(m_pRSAPri != NULL)
{
RSA_free(m_pRSAPri);
}
m_pRSAPri = RSAPrivateKey_dup(rsa);

// 生成公钥文件
if(!m_sPubKeyFile.empty())
{
BIO *bp = BIO_new( BIO_s_file() );  
BIO_write_filename( bp, const_cast<char*>(m_sPubKeyFile.c_str()));  
PEM_write_bio_RSA_PUBKEY(bp, rsa);  
BIO_free_all( bp );   

// 读取秘钥文件内容到成员变量中
GetKeyFileContent(m_sPubKeyFile, m_sPubKey);
}

// 生成私钥文件
if(!m_sPriKeyFile.empty())
{
BIO *bp = BIO_new_file(m_sPriKeyFile.c_str(), "w+");  

// 是否加密
if(strlen(m_sPriKeyPwd) > 0)
{
PEM_write_bio_RSAPrivateKey(bp, rsa, EVP_des_ede3(), (unsigned char*)m_sPriKeyPwd, strlen(m_sPriKeyPwd), NULL, NULL);  
}
else
{
PEM_write_bio_RSAPrivateKey(bp, rsa, NULL, NULL, NULL, NULL, NULL);  
}

BIO_free_all( bp ); 

// 读取秘钥文件内容到成员变量中
GetKeyFileContent(m_sPriKeyFile, m_sPriKey);
}

RSA_free(rsa);  

}

// 读取公钥-文件

bool COpenSSLRSA::ReadPubRSAByFile()

{  
bool bRet = true;

if(m_pRSAPub != NULL)
{
RSA_free(m_pRSAPub);
}

BIO* bp = BIO_new( BIO_s_file() );  
BIO_read_filename( bp, m_sPubKeyFile.c_str() );  
m_pRSAPub = PEM_read_bio_RSA_PUBKEY( bp, NULL, NULL, NULL );  
if (NULL == m_pRSAPub) 
{  
PrintErrMsg(0, "ReadPubRSAByFile");
bRet = false;
}

BIO_free_all( bp );  

return bRet;  

}

// 读取私钥-文件

bool COpenSSLRSA::ReadPriRSAByFile()

{  
OpenSSL_add_all_algorithms(); 

bool bRet = true;

if(m_pRSAPri != NULL)
{
RSA_free(m_pRSAPri);
}

BIO* bp = BIO_new( BIO_s_file() );  
BIO_read_filename( bp, m_sPriKeyFile.c_str());  
m_pRSAPri = PEM_read_bio_RSAPrivateKey( bp, NULL, NULL, m_sPriKeyPwd);  
if (NULL == m_pRSAPri) 
{  
PrintErrMsg(0, "ReadPriRSAByFile");
bRet = false;
}

BIO_free_all( bp );  

// 解决内存泄漏
EVP_cleanup();

return bRet;  

}

// 读取公钥-内存

bool COpenSSLRSA::ReadPubRSAByMem(bool bNeedFormat)

{
bool bRet = false;

if(m_pRSAPub != NULL)
{
RSA_free(m_pRSAPub);
}

// 如果不是完整的,则格式化
if(bNeedFormat)
{
int nKeyLen = m_sPubKey.size();      //strPublicKey为base64编码的公钥字符串
for(int i = 64; i < nKeyLen; i+=64)
{
if(m_sPubKey[i] != '\n')
{
m_sPubKey.insert(i, "\n");
}
i++;
}
m_sPubKey.insert(0, "-----BEGIN PUBLIC KEY-----\n");
m_sPubKey.append("\n-----END PUBLIC KEY-----\n");
}

BIO *bio = NULL; 

char *chKey = const_cast<char *>(m_sPubKey.c_str());
if ((bio = BIO_new_mem_buf(chKey, -1)) == NULL)       //从字符串读取RSA公钥
{     
sprintf(m_sErrMsg, "BIO_new_mem_buf failed!\n");      
printf(m_sErrMsg);
return bRet;
}       
m_pRSAPub = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);   //从bio结构中得到rsa结构

if (m_pRSAPub == NULL)
{
PrintErrMsg(0, "ReadPubRSAByMem");
bRet = false;
}
else
{
bRet = true;
}

BIO_free_all(bio);

return bRet;

}

// 读取私钥-内存

bool COpenSSLRSA::ReadPriRSAByMem(bool bNeedFormat)

{
bool bRet = false;

if(m_pRSAPri != NULL)
{
RSA_free(m_pRSAPri);
}

// 如果不是完整的,则格式化
if(bNeedFormat)
{
int nKeyLen = m_sPriKey.size();      //strPublicKey为base64编码的公钥字符串
for(int i = 64; i < nKeyLen; i+=64)
{
if(m_sPriKey[i] != '\n')
{
m_sPriKey.insert(i, "\n");
}
i++;
}
m_sPriKey.insert(0, "-----BEGIN RSA PRIVATE KEY-----\n");
m_sPriKey.append("\n-----END RSA PRIVATE KEY-----\n");
}

BIO *bio = NULL; 

char *chKey = const_cast<char *>(m_sPriKey.c_str());
if ((bio = BIO_new_mem_buf(chKey, -1)) == NULL)       //从字符串读取RSA公钥
{     
sprintf(m_sErrMsg, "BIO_new_mem_buf failed!\n");    
printf(m_sErrMsg);
return bRet;
}       
m_pRSAPri = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);   //从bio结构中得到rsa结构
if (m_pRSAPri == NULL)
{
PrintErrMsg(0, "ReadPriRSAByMem");
bRet = false;
}
else
{
bRet = true;
}

BIO_free_all(bio);

return bRet;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  openssl