C++ Aes与Rsa加密算法使用

GitHub

AesTest.h

#ifndef AES_TEST_H
#define AES_TEST_H

#include 


bool AesEncrypt(unsigned char* in, unsigned char* out, size_t len, const unsigned char* key, size_t keyLen = 32);

bool AesDecrypt(unsigned char* in, unsigned char* out, size_t len, const unsigned char* key, size_t keyLen = 32);

void TestAes();


#endif

AesTest.cpp

#include "AesTest.h"
#include 
#include 

using namespace std;

const unsigned char g_Key1[16] = { 'q', '*', 'y', 'u', '3', '7', '@', 't', 'n', '#', '6', '~', 'K', 'n', 'C', '!'};
const unsigned char g_Key2[32] = { 'q', '*', 'y', 'u', '3', '7', '@', 't', 'n', '#', '6', '~', 'K', 'n', 'C', '!', 'q', '*', 'y', 'u', '3', '7', '@', 't', 'n', '#', '6', '~', 'K', 'n', 'C', '!'};

bool AesEncrypt(unsigned char* in, unsigned char* out, size_t len, const unsigned char* key, size_t keyLen)
{
	AES_KEY aesKey;
	memset(&aesKey, 0x00, sizeof(AES_KEY));
	if (AES_set_encrypt_key(key, keyLen * 8, &aesKey) < 0)
	{
		fprintf(stderr, "Unable to set encrypt key in AES...\n");
		return false;
	}
	int count = len / AES_BLOCK_SIZE;
	int remainder = len % AES_BLOCK_SIZE;
	for (int i = 0; i < count; i++)
	{
		AES_encrypt(in + i * AES_BLOCK_SIZE, out + i * AES_BLOCK_SIZE, &aesKey);
	}
	if (remainder != 0)
	{
		unsigned char temp[AES_BLOCK_SIZE];
		memset(temp, 0, sizeof(temp));
		memcpy(temp, in + count * AES_BLOCK_SIZE, remainder);
		AES_encrypt(temp, out + count * AES_BLOCK_SIZE, &aesKey);
	}
	return true;
}

bool AesDecrypt(unsigned char* in, unsigned char* out, size_t len, const unsigned char* key, size_t keyLen)
{
	AES_KEY aesKey;
	memset(&aesKey, 0x00, sizeof(AES_KEY));
	if (AES_set_decrypt_key(key, keyLen * 8, &aesKey) < 0)
	{
		fprintf(stderr, "Unable to set decrypt key in AES...\n");
		return false;
	}
	int count = len / AES_BLOCK_SIZE;
	for (int i = 0; i < count; i++)
	{
		AES_decrypt(in + i * AES_BLOCK_SIZE, out + i * AES_BLOCK_SIZE, &aesKey);
	}
	return true;
}

void TestAes()
{
	cout << endl << "----TestAes Start----" << endl << endl;

	string data = "Hello World From Openssl. 你好,世界!来自Openssl。";
	cout << "data=[" << data.c_str() << "], Len=[" << data.length() << "]" << endl;

	unsigned char encryptData[1024] = { 0 };
	unsigned char decryptData[1024] = { 0 };
	int encryptLen = data.length();
	if (encryptLen % AES_BLOCK_SIZE != 0)
	{
		encryptLen += AES_BLOCK_SIZE - encryptLen % AES_BLOCK_SIZE;
	}

	AesEncrypt((unsigned char*)data.c_str(), encryptData, data.length(), g_Key2, 32);
	AesDecrypt(encryptData, decryptData, strlen((char*)encryptData), g_Key2, 32);

	cout << "encryptLen = [" << encryptLen << "]" << endl;
	cout << "decryptData = [" << decryptData << "], strLen = [" << strlen((char*)decryptData) << "]" << endl;

	cout << endl << "----TestAes End----" << endl << endl;
}

RsaTest.h

#ifndef RSA_TEST_H
#define RSA_TEST_H

#include 

bool RsaGenerateKey();

RSA* GetPubKey();

RSA* GetPriKey();


bool RsaPublicEncrypt(unsigned char* in, int inLen, unsigned char* out, int& outLen);

bool RsaPublicDecrypt(unsigned char* in, int inLen, unsigned char* out, int& outLen);

bool RsaPrivateEncrypt(unsigned char* in, int inLen, unsigned char* out, int& outLen);

bool RsaPrivateDecrypt(unsigned char* in, int inLen, unsigned char* out, int& outLen);

void TestRsa(bool pubEncrypt);

#endif

RsaTest.cpp

#include "RsaTest.h"
#include 

using namespace std;

#define  MAX_RSA_KEY_LENGTH 1024

static const char* PUBLIC_KEY_FILE = "pubkey.key";
static const char* PRIVATE_KEY_FILE = "prikey.key";

bool RsaGenerateKey()
{
	if (auto f = fopen("PUBLIC_KEY_FILE", "r"))
	{
		fclose(f);
		return true;
	}

	RSA* rsa = RSA_new();
	rsa = RSA_generate_key(MAX_RSA_KEY_LENGTH, RSA_F4, nullptr, nullptr);

	unsigned char pubKeyData[MAX_RSA_KEY_LENGTH] = { 0 };
	int pubKeyLen = i2d_RSAPublicKey(rsa, nullptr);
	unsigned char* p = pubKeyData;
	pubKeyLen = i2d_RSAPublicKey(rsa, &p);

	unsigned char priKeyData[MAX_RSA_KEY_LENGTH] = { 0 };
	int priKeyLen = i2d_RSAPrivateKey(rsa, nullptr);
	unsigned char* p2 = priKeyData;
	priKeyLen = i2d_RSAPrivateKey(rsa, &p2);


	FILE* pubKeyFile = nullptr;
	pubKeyFile = fopen(PUBLIC_KEY_FILE, "wb");
	if (pubKeyFile == nullptr)
	{
		cout << "fopen pubkey.key failed!" << endl;
		return false;
	}
	fwrite(pubKeyData, 1, pubKeyLen, pubKeyFile);
	fclose(pubKeyFile);

	FILE* priKeyFile = nullptr;
	priKeyFile = fopen(PRIVATE_KEY_FILE, "wb");
	if (priKeyFile == nullptr)
	{
		cout << "fopen prikey.key failed!" << endl;
		return false;
	}
	fwrite(priKeyData, 1, priKeyLen, priKeyFile);
	fclose(priKeyFile);

	if (rsa != nullptr)
	{
		RSA_free(rsa);
		rsa = nullptr;
	}
	return true;
}

RSA* GetPubKey()
{
	unsigned char pubKeyData[MAX_RSA_KEY_LENGTH] = { 0 };
	FILE* pubKeyFile = nullptr;
	pubKeyFile = fopen(PUBLIC_KEY_FILE, "rb");
	if (pubKeyFile == nullptr)
	{
		cout << "fopen pubkey.key failed!" << endl;
		return nullptr;
	}
	fseek(pubKeyFile, 0, SEEK_END);
	int len = ftell(pubKeyFile);
	fseek(pubKeyFile, 0, SEEK_SET);
	fread(pubKeyData, 1, len, pubKeyFile);
	fclose(pubKeyFile);

	RSA* rsa = RSA_new();
	
	const unsigned char* p = pubKeyData;
	rsa = d2i_RSAPublicKey(nullptr, &p, len);
	if (rsa == nullptr)
	{
		cout << "GetPubKey Failed!" << endl;
		return nullptr;
	}
	return rsa;
}
RSA* GetPriKey()
{
	unsigned char priKeyData[MAX_RSA_KEY_LENGTH] = { 0 };
	FILE* priKeyFile = nullptr;
	priKeyFile = fopen(PRIVATE_KEY_FILE, "rb");
	if (priKeyFile == nullptr)
	{
		cout << "fopen prikey.key failed!" << endl;
		return nullptr;
	}
	fseek(priKeyFile, 0, SEEK_END);
	int len = ftell(priKeyFile);
	fseek(priKeyFile, 0, SEEK_SET);
	fread(priKeyData, 1, len, priKeyFile);
	fclose(priKeyFile);

	RSA* rsa = RSA_new();

	const unsigned char* p = priKeyData;
	rsa = d2i_RSAPrivateKey(nullptr, &p, len);
	if (rsa == nullptr)
	{
		cout << "GetPriKey Failed!" << endl;
		return nullptr;
	}
	return rsa;
}

bool RsaPublicEncrypt(unsigned char* in, int inLen, unsigned char* out, int& outLen)
{
	RSA* rsa = GetPubKey();
	if (rsa == nullptr)
	{
		return false;
	}

	outLen = RSA_public_encrypt(inLen, in, out, rsa, RSA_PKCS1_PADDING);
	return true;
}
bool RsaPublicDecrypt(unsigned char* in, int inLen, unsigned char* out, int& outLen)
{
	RSA* rsa = GetPubKey();
	if (rsa == nullptr)
	{
		return false;
	}

	outLen = RSA_public_decrypt(inLen, in, out, rsa, RSA_PKCS1_PADDING);
	return true;
}
bool RsaPrivateEncrypt(unsigned char* in, int inLen, unsigned char* out, int& outLen)
{
	RSA* rsa = GetPriKey();
	if (rsa == nullptr)
	{
		return false;
	}

	outLen = RSA_private_encrypt(inLen, in, out, rsa, RSA_PKCS1_PADDING);
	return true;
}
bool RsaPrivateDecrypt(unsigned char* in, int inLen, unsigned char* out, int& outLen)
{
	RSA* rsa = GetPriKey();
	if (rsa == nullptr)
	{
		return false;
	}

	outLen = RSA_private_decrypt(inLen, in, out, rsa, RSA_PKCS1_PADDING);
	return true;
}


void TestRsa(bool pubEncrypt)
{
	cout << endl << "----TestRsa Start----" << endl << endl;
	cout << "pubEncrypt:" << pubEncrypt << endl;
	
	string data = "Hello World From Openssl. 你好,世界!来自Openssl。";
	cout << "data=[" << data.c_str() << "], Len=[" << data.length() << "]" << endl;
	unsigned char encryptData[1024] = { 0 };
	unsigned char decryptData[1024] = { 0 };
	int encryptLen = 0, decryptLen = 0;

	RsaGenerateKey();
	if(pubEncrypt)
	{
		RsaPublicEncrypt((unsigned char*)data.c_str(), data.length(), encryptData, encryptLen);
		RsaPrivateDecrypt(encryptData, encryptLen, decryptData, decryptLen);
	}
	else
	{
		RsaPrivateEncrypt((unsigned char*)data.c_str(), data.length(), encryptData, encryptLen);
		RsaPublicDecrypt(encryptData, encryptLen, decryptData, decryptLen);
	}

	cout << "encryptData: strLen = [" << strlen((char*)encryptData) << "], encryptLen = [" << encryptLen << "]" << endl;
	cout << "decryptData = [" << decryptData << "], strLen = [" << strlen((char*)decryptData) << "], decryptLen = [" << decryptLen << "]" << endl;
	cout << endl << "----TestRsa End----" << endl << endl;
}

test.cpp

#include "AesTest.h"
#include "RsaTest.h"
#include 

using namespace std;

int main()
{
	TestAes();
	TestRsa(true);
	TestRsa(false);

	return 0;
}

 

输出:


----TestAes Start----

data=[Hello World From Openssl. 你好,世界!来自Openssl。], Len=[51]
encryptLen = [64]
decryptData = [Hello World From Openssl. 你好,世界!来自Openssl。], strLen = [51]

----TestAes End----


----TestRsa Start----

pubEncrypt:1
data=[Hello World From Openssl. 你好,世界!来自Openssl。], Len=[51]
encryptData: strLen = [128], encryptLen = [128]
decryptData = [Hello World From Openssl. 你好,世界!来自Openssl。], strLen = [51], decryptLen = [51]

----TestRsa End----


----TestRsa Start----

pubEncrypt:0
data=[Hello World From Openssl. 你好,世界!来自Openssl。], Len=[51]
encryptData: strLen = [128], encryptLen = [128]
decryptData = [Hello World From Openssl. 你好,世界!来自Openssl。], strLen = [51], decryptLen = [51]

----TestRsa End----


E:\SVN\AMS\01_trade_branches\3.0.6\test\openssl_test2\build\Debug\openssl_test2.exe (进程 45908)已退出,代码为 0。

 

你可能感兴趣的:(C++,OpenSSL,openssl,安全)