Crypto++库实现AES和RSA加密解密

发布时间 2023-09-07 14:53:07作者: DoubleLi

本文介绍使用Crypto++进行AES加密和RSA加密

Crypto++库在VS中配置方法

Crypto++库下载地址:
https://www.cryptopp.com/,
目前已经更新到8.1版本。本文使用的是8.1版本的Crypto++。

下载压缩包后解压,然后用vs中编译cryptopp。生成debug和Realease版本的cryptlib.lib静态库。在使用时只要包含相应功能的头文件。

#include "D:\cryptopp810\randpool.h"
#include "D:\cryptopp810\rsa.h"
#include "D:\cryptopp810\hex.h"
#include "D:\cryptopp810\files.h"
#include "D:\cryptopp810\osrng.h"
#include "D:\cryptopp810\base64.h"
using namespace CryptoPP;

和引入lib包

#pragma comment(lib, "cryptlib.lib")

AES加密

AES加密算法是对称秘钥加密中最流行的算法之一。加密的区块长度是16个字节。

//变量准备
unsigned char aesKey[AES::DEFAULT_KEYLENGTH]; //密钥
unsigned char inBlock[AES::BLOCKSIZE] = "ABCDEF"; //要加密的数据块,小于16字节
unsigned char outBlock[AES::BLOCKSIZE]; //加密后的密文块
unsigned char xorBlock[AES::BLOCKSIZE]; //必须设定为全零
memset(xorBlock, 0, AES::BLOCKSIZE); //置零

//随机生成key
AutoSeededRandomPool rnd;
SecByteBlock key(0x00, AES::DEFAULT_KEYLENGTH);
rnd.GenerateBlock(key, key.size());

//加密
AESEncryption aesEncryptor; 
aesEncryptor.SetKey(key, AES::DEFAULT_KEYLENGTH); 
aesEncryptor.ProcessAndXorBlock(inBlock, xorBlock, outBlock);


//解密
AESDecryption aesDecryptor;
unsigned char plainText[AES::BLOCKSIZE];
aesDecryptor.SetKey(key, AES::DEFAULT_KEYLENGTH);
aesDecryptor.ProcessAndXorBlock(outBlock, xorBlock, plainText);

 //打印解密结果
for (int i = 0; i<16; i++)
{
	cout << plainText[i];
}
cout << endl;

RSA加密

RSA加密算法是一种非对称加密算法,是第一个既能用于数据加密也能用于数字签名的算法可用于加密
和签名。该算法需要一对秘钥,即私钥和公钥。其中
私钥由用户保存,不对外公开,公钥公开发布。使用公钥加密的信息,可以使用私钥解密。使用私钥签名的
数据,可以使用公钥验证。

秘钥生成

//根据长度生成公钥和私钥,并分别保存到pubFilename文件和privFilename文件
void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename)
{
	AutoSeededRandomPool rng;
	InvertibleRSAFunction privkey;
	privkey.GenerateRandomWithKeySize(rng, keyLength);

	Base64Encoder privkeysink(new FileSink(privFilename));  //"privkey.txt"
	privkey.DEREncode(privkeysink);
	privkeysink.MessageEnd();

	RSAFunction pubkey(privkey);
	Base64Encoder pubkeysink(new FileSink(pubFilename));  //"pubkey.txt"
	pubkey.DEREncode(pubkeysink);
	pubkeysink.MessageEnd();
}

信息加密(从文件读取公钥)

//把字符串plain中的内容用pubFilename文件中的公钥加密数据并保存到encryptedFilename中。
void Encrypt(const string &plain, const char *pubFilename, const char *encryptedFilename)
{
	RSAES_OAEP_SHA_Encryptor pubkey(FileSource(pubFilename, true, new Base64Decoder));

	SecByteBlock sbbCipherText(pubkey.CiphertextLength(plain.size()));
	//sbbCipherText.begin();
	AutoSeededRandomPool rng;
	pubkey.Encrypt(
		rng,
		(byte const*)plain.data(),
		plain.size(),
		sbbCipherText.begin());

	FileSink(encryptedFilename).Put(sbbCipherText.begin(), sbbCipherText.size());
}

信息加密(公钥写到代码中)

void Encrypt2(const string &plain,const char *encryptedFilename)
{
	//RSAES_OAEP_SHA_Encryptor pubkey(FileSource(pubFilename, true, new Base64Decoder));
	string pub = "MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQC1f+WV5dAiVb2w1lgf21Wz84Uuou1TwCJ+\
		ivxcpijobsHQLOLMakYSyRonH6SQJtL5CHXycBubA9sS7F2nVG2fMn6z9Ev11nu7J4IPPF9u\
		v / ZqwAIlXwxVPsl4K69rWmdP4i5ezj++I7nC + kX6qjxpcyhnQalKAl2OC8AMNEo0awIBEQ == ";
	RSAES_OAEP_SHA_Encryptor pubkey(StringSource(pub, true, new Base64Decoder));

	SecByteBlock sbbCipherText(pubkey.CiphertextLength(plain.size()));
	//sbbCipherText.begin();
	AutoSeededRandomPool rng;
	pubkey.Encrypt(
		rng,
		(byte const*)plain.data(),
		plain.size(),
		sbbCipherText.begin());

	FileSink(encryptedFilename).Put(sbbCipherText.begin(), sbbCipherText.size());
}

用私钥解密(从文件读取私钥)

//用privFilename文件中的私钥解密encryptedFilename文件中的加密内容,并返回解密内容。
string Decrypt(const char *privFilename, const char *encryptedFilename)
{
	string strContents, recovered;
	FileSource(encryptedFilename, true, new StringSink(strContents));
	AutoSeededRandomPool rng;
	RSAES_OAEP_SHA_Decryptor privkey(FileSource(privFilename, true, new Base64Decoder));
	StringSource(strContents, true, new PK_DecryptorFilter(rng, privkey, new StringSink(recovered)));
	return recovered;
}

 

用私钥解密(私钥写到代码中)

string Decrypt2(const char *encryptedFilename)
{
	string pri = "MIICdAIBADANBgkqhkiG9w0BAQEFAASCAl4wggJaAgEAAoGBALV/5ZXl0CJVvbDWWB/bVbPz\
		hS6i7VPAIn6K / FymKOhuwdAs4sxqRhLJGicfpJAm0vkIdfJwG5sD2xLsXadUbZ8yfrP0S / XW\
		e7sngg88X26 / 9mrAAiVfDFU + yXgrr2taZ0 / iLl7OP74jucL6RfqqPGlzKGdBqUoCXY4LwAw0\
		SjRrAgERAoGAJV4YreuMu8ZbwoZ7jhaRpQx9TV3HcyAHGg2OT09ixnEn5xhMz7uG5b / 92uDe\
		Ha2j5 / o2Zp6cRY / aR6kiVyf4cz / 3FHUW0sGpLRPuE0YePQFg / +z88iNyafOsNXC7XrOUlbP2\
		hK9cNbk / 43L0NXj3cSXPndzI7CP45gB7xl8KB2kCQQC9mFlx7VFYK3fYBrPpsOdwze604m7L\
		v9jRRIDIEGtQKUHwLx0PYOxQnolOliQtALuDsK66dxOsroAWc13 + UlEJAkEA9RGuAIISiIhD\
		yhuP / huoI + Og + cDVVNeeYECGG36hxpDtrHZ0IfpfKsBWoekb6InRgPUC6RkpFKz58vN8 + qKa\
		0wJALJxRR / uaq1WFnD3P + sA2dOUpG4CSiktCEx8tXEAZQAm1KXR / TumhA + kRP6rbVeIOAN5H\
		Ou7Xc + zS2BslLMgTEQJBAMnSUw96LWFhKMSPK0m8bFnKhJFxoKA5GQP45ul3WAzv0spDbrKR\
		9AUW3e6 / +N2erIhRTbDniz40GSJuKrBJrK0CQH/hg5LLpMx80oX6JUfQFfYYZ7FkgBwfEh8v\
		iUmE + zgondETTnULzWU9JxoQxrkRfg0qu9NcTPZQ5oqv+VnUKH4=";
	string strContents, recovered;
	FileSource(encryptedFilename, true, new StringSink(strContents));
	AutoSeededRandomPool rng;
	RSAES_OAEP_SHA_Decryptor privkey(StringSource(pri, true, new Base64Decoder));
	StringSource(strContents, true, new PK_DecryptorFilter(rng, privkey, new StringSink(recovered)));
	return recovered;
}

用私钥签名信息

void sign(const char *privFilename, const char *tobesignedFilename, const char *signedFilename)
{
	RSASSA_PKCS1v15_SHA_Signer privkey(FileSource(privFilename, true, new Base64Decoder));
	AutoSeededRandomPool rng;
	FileSource(tobesignedFilename, true, new SignerFilter(rng, privkey, new HexEncoder(new FileSink(signedFilename))));
}

用公钥验证

void ver(const char *pubFilename, const char *tobesignedFilename, const char *signedFilename)
{
	RSASSA_PKCS1v15_SHA_Verifier pubkey(FileSource(pubFilename, true, new Base64Decoder));

	AutoSeededRandomPool rng;
	FileSource signatureFile(signedFilename, true, new HexDecoder);

	if (signatureFile.MaxRetrievable() != pubkey.SignatureLength())
	{
		printf("\nNO\n");
		return;
	}
	SecByteBlock signature(pubkey.SignatureLength());
	signatureFile.Get(signature, signature.size());

	SignatureVerificationFilter *verifierFilter = new SignatureVerificationFilter(pubkey);
	verifierFilter->Put(signature, pubkey.SignatureLength());
	FileSource(tobesignedFilename, true, verifierFilter);
	printf("\n%d\n", verifierFilter->GetLastResult());
}

使用方法

	char priKeyFile[128] = { 0 };
	char pubKeyFile[128] = { 0 };
	char encryptedFile[128] = { 0 };

	strcpy(priKeyFile, "privkey.txt");  // 私钥文件名
	strcpy(pubKeyFile, "pubkey.txt");  // 公钥文件名
	strcpy(encryptedFile, "encrypted.dat");

	//生成RSA公钥和私钥
	GenerateRSAKey(1024, priKeyFile, pubKeyFile);

	string str = "123ADS 123ADS 123ADS 123ADS";

	Encrypt(str, pubKeyFile, encryptedFile);
	string re = Decrypt(priKeyFile, encryptedFile);
    cout << re << endl;