crypto++(cryptopp)加密库aes算法的使用

整个过程浪费了几个小时,感觉cryptopp库的源码不太友好。
遇到的坑和解决办法记录如下,可能不同环境会有不同的问题:
1、下载官网地址 https://www.cryptopp.com/#download 当前最新的是版本8.6(2022.05.21)
2、我需要的是动态库cryptdll.vcxproj(win10 vs2017 qt5.14.2),静态库编译出来有70多M,动态库lib和dll一共才3M左右。
3、编译好像没问题(整个sln一起编译才行),按照例子使用时报错,
一是base64.h.cpp等文件没加到cryptdll工程中
二是base64.h等文件没设置导出类,自己加CRYPTOPP_DLL导出,例如:

class CRYPTOPP_DLL Base64Encoder : public SimpleProxyFilter
 三是报一个导出量找不到,怀疑是语法问题,最终是直接不导出const变量,直接改为h文件中的常量就行了,本身它也是个const常量,不知道是不是部分编译器支持const常量的导出,vs刚好不支持。

4、接口封装后的示例

const QString str_aes = aes_encrypt(str);
const QString str_d = aes_decrypt(str_aes);//aes解码

5、实现(麻烦的地方在于,找到能让示例代码运行起来的key和iv)

const byte aes_key[CryptoPP::AES::DEFAULT_KEYLENGTH] = {'1', '2', '3', '4', '5', '6',
                                                         '7', '8', '9', '0', '11', '12',
														 '13', '14', '15', 0 }; // 16字节
const byte aes_iv[CryptoPP::AES::BLOCKSIZE] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11, 12, 13,14, 0 }; // 16字节 密钥偏移量

std::string aes_encrypt(std::string data)
{
	return aes_encrypt((unsigned char*)aes_key, 16, (unsigned char*)aes_iv, data);
}
std::string aes_decrypt(std::string base64_data)
{
	return aes_decrypt((unsigned char*)aes_key, 16, (unsigned char*)aes_iv, base64_data);
}

以下代码参考 https://blog.csdn.net/ecrisraul/article/details/88040912 
// AES编码,返回的是base64编码的数据
std::string aes_encrypt(unsigned char* key, int keylen, unsigned char* iv, std::string data)
{
	std::string encrypt_str;
	try {
		// 初始化编码器 这里选择的mode是CBC_Mode
		CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption cbc_encription(key, keylen, iv);
		// 设置一个流格式化 CryptoPP很好用的一个模块
		CryptoPP::StreamTransformationFilter stf_encription(cbc_encription,
			// 这里使加密的输出流用base64编码,如果不需要则直接传new CryptoPP::StringSink(encrypt_str)
			new CryptoPP::Base64Encoder(new CryptoPP::StringSink(encrypt_str)),
			// 填充模式是填充0
			CryptoPP::BlockPaddingSchemeDef::ZEROS_PADDING);
		// put将需要编码的数据传入
		stf_encription.Put(reinterpret_cast<const unsigned char*>(data.c_str()), data.length() + 1);
		stf_encription.MessageEnd();
	}
	catch (std::exception e) {
		std::cout << e.what() << std::endl;
	}
	return encrypt_str;
}
// aes解密,这里传入的base64_data是AES加密后用base64编码得到的数据
std::string aes_decrypt(unsigned char* key, int keylen, unsigned char* iv, std::string base64_data)
{
	try {
		// 没有找到输入流的前置处理接口,这里先做base64解码
		std::string aes_encrypt_data;
		CryptoPP::Base64Decoder decoder;
		decoder.Attach(new CryptoPP::StringSink(aes_encrypt_data));
		decoder.Put(reinterpret_cast<const unsigned char*>(base64_data.c_str()), base64_data.length());
		decoder.MessageEnd();

		// 类似AES加密,得到原始数据
		std::string decrypt_data;
		CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption cbc_description(key, keylen, iv);
		CryptoPP::StreamTransformationFilter stf_description(cbc_description,
			new CryptoPP::StringSink(decrypt_data), CryptoPP::BlockPaddingSchemeDef::ZEROS_PADDING);
		stf_description.Put(reinterpret_cast<const unsigned char*>(aes_encrypt_data.c_str())
			, aes_encrypt_data.length());
		stf_description.MessageEnd();
		return decrypt_data;
	}
	catch (std::exception e) {
		std::cout << e.what() << std::endl;
		return "";
	}
}

网上有的代码拿过来能编译能跑,但总是崩溃,也许是我key和iv设置不得要领,反正浪费了几个小时。
以上是在我本机确实可用的代码。

你可能感兴趣的:(算法,加密,crypto,crypto++,cryptopp,aes)