本文介绍使用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;