#include "stdafx.h"
#include "newOpenssl.h"
#include "base64.h"
#include <openssl\aes.h>
#include <openssl\err.h>
#include <openssl\rsa.h>
#include <openssl\rand.h>
#include <openssl\pem.h>
#define RSA_PUBLIC_KEY "rsa_public_key.pem"
#define RSA_PRIVATE_KEY "rsa_private_key.pem"
#define AES_LENGTH 128
void newOpenssl::RSAmain()
{
BASE64 base64;
int rsaLength = 0;
std::string source = "中文测试 中文测试 English Test English Test 123 321 ,./ #@!";
source = stringToUTF8(source);
printf_s("Source is:%s\n\n", source.c_str());
std::string rsa = RSAEncrypt(RSA_PUBLIC_KEY, source, rsaLength);
printf_s("RSA encrypt is:%s\n\n", rsa.c_str());
std::string rsa_d = RSADecrypt(RSA_PRIVATE_KEY, rsa);
printf_s("RSA decrypt is:%s\n\n", rsa_d.c_str());
std::string base64_e = base64.encode(rsa);
printf_s("Base64 encode is:%s\n\n", base64_e.c_str());
std::string base64_d = base64.decode(base64_e);
printf_s("Base64 decode is:%s\n\n", base64_d.c_str());
std::string base64_rsa_d = RSADecrypt(RSA_PRIVATE_KEY, base64_d);
printf_s("Base64 to RSA decode is:%s\n\n", base64_rsa_d.c_str());
}
std::string newOpenssl::RSAEncrypt(const std::string &strPemFileName, const std::string &strData, int &rsaLength)
{
FILE *pemFile = NULL;
std::string strResult;
int nLen = 0;
char *pEncode = NULL;
RSA *rsa = RSA_new();
if (strPemFileName == "" || strData == "")
{
return "";
}
if (fopen_s(&pemFile, strPemFileName.c_str(), "r") != 0)
{
return "";
}
if (PEM_read_RSA_PUBKEY(pemFile, &rsa, NULL, NULL) == NULL)
{
return "";
}
nLen = RSA_size(rsa);
pEncode = (char*)malloc(nLen + 1);
int ret = RSA_public_encrypt(strData.length(), (const unsigned char*)strData.c_str(), (unsigned char*)pEncode, rsa, RSA_PKCS1_PADDING);
if (ret >= 0)
{
strResult = std::string(pEncode, ret);
}
free(pEncode);
RSA_free(rsa);
fclose(pemFile);
CRYPTO_cleanup_all_ex_data();
rsaLength = nLen;
return strResult;
}
std::string newOpenssl::RSADecrypt(const std::string & strPemFileName, const std::string & strData)
{
FILE *pemFile = NULL;
std::string strResult;
int nLen = 0;
char *pEncode = NULL;
RSA *rsa = RSA_new();
if (strPemFileName == "" || strData == "")
{
return "";
}
if (fopen_s(&pemFile, strPemFileName.c_str(), "r") != 0)
{
return "";
}
if (PEM_read_RSAPrivateKey(pemFile, &rsa, NULL, NULL) == NULL)
{
return "";
}
nLen = RSA_size(rsa);
pEncode =(char*)malloc(nLen + 1);
int ret = RSA_private_decrypt(strData.length(), (const unsigned char*)strData.c_str(), (unsigned char*)pEncode, rsa, RSA_PKCS1_PADDING);
if (ret >= 0)
{
strResult = std::string(pEncode, ret);
}
free(pEncode);
RSA_free(rsa);
fclose(pemFile);
CRYPTO_cleanup_all_ex_data();
return strResult;
}
void newOpenssl::AESmain()
{
BASE64 base64;
char key[AES_BLOCK_SIZE];
char sourceStringTemp[AES_LENGTH];
char dstStringTemp[AES_LENGTH];
memset((char*)sourceStringTemp, 0, AES_LENGTH);
memset((char*)dstStringTemp, 0, AES_LENGTH);
std::string str = "test1236666666666666666666666666666666666666666666666666666666666666666666666666666666666666666";
strcpy_s(key, "123123123123123");
AES_Encrypt(str.c_str(), key, dstStringTemp, str.length());
printf("aes_en:%s:\n\n", dstStringTemp);
std::string str2 = base64.encode(dstStringTemp);
printf("aes_base64:%s\n\n", str2.c_str());
std::string str3 = base64.decode(str2);
printf("aes_base64_de:%s\n\n", str3.c_str());
memset((char*)sourceStringTemp, 0, AES_LENGTH);
AES_Decrypt(str3, key, sourceStringTemp);
printf("aes_de:%s\n\n", sourceStringTemp);
}
int newOpenssl::AES_Encrypt(const std::string data, char * key, char * out, int length)
{
if (!data.c_str() || !key || !out) return 0;
unsigned char iv[AES_BLOCK_SIZE];//加密的初始化向量
for (int i = 0; i<AES_BLOCK_SIZE; ++i)//iv一般设置为全0,可以设置其他,但是加密解密要一样就行
iv[i] = 0;
AES_KEY aes;
if (AES_set_encrypt_key((unsigned char*)key, 128, &aes) < 0)
{
return 0;
}
int len = length;//这里的长度是char*in的长度,但是如果in中间包含'\0'字符的话
//那么就只会加密前面'\0'前面的一段,所以,这个len可以作为参数传进来,记录in的长度
//至于解密也是一个道理,光以'\0'来判断字符串长度,确有不妥,后面都是一个道理。
AES_cbc_encrypt((unsigned char*)data.c_str(), (unsigned char*)out, len, &aes, iv, AES_ENCRYPT);
return 1;
}
int newOpenssl::AES_Decrypt(std::string data, char * key, char * out)
{
if (!data.c_str() || !key || !out) return 0;
unsigned char iv[AES_BLOCK_SIZE];//加密的初始化向量
for (int i = 0; i<AES_BLOCK_SIZE; ++i)//iv一般设置为全0,可以设置其他,但是加密解密要一样就行
iv[i] = 0;
AES_KEY aes;
if (AES_set_decrypt_key((unsigned char*)key, 128, &aes) < 0)
{
return 0;
}
int len = data.length();
AES_cbc_encrypt((unsigned char*)data.c_str(), (unsigned char*)out, len, &aes, iv, AES_DECRYPT);
return 1;
}
std::string newOpenssl::stringToUTF8(const std::string & str)
{
int nwLen = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
wchar_t *pwBuf = new wchar_t[nwLen + 1]; //防止出现尾巴
ZeroMemory(pwBuf, nwLen * 2 + 2);
::MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), pwBuf, nwLen);
int nLen = ::WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, NULL, NULL, NULL);
char *pBuf = new char[nLen + 1];
ZeroMemory(pBuf, nLen + 1);
::WideCharToMultiByte(CP_UTF8, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);
std::string retStr(pBuf);
delete[] pwBuf; pwBuf = NULL;
delete[] pBuf; pBuf = NULL;
return retStr;
}