整个过程浪费了几个小时,感觉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设置不得要领,反正浪费了几个小时。
以上是在我本机确实可用的代码。