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

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
经常看到有人要找AES-GCM-128  这个算法加解密 网上相关的文档也较少其中在telegram登录首页就在使用算法 应该让不少哥们头疼 其实这个加密常见于浏览器内置接口window.crypto.subtle 该接口不仅支持该类型的加密 且支持非常多的算法加密如RSA DES  等等  这里就演示AES-GCM-128 这个类型 crypto-AES-GCM-128调用例子 function ___crypto__test(keyData, iv, data) {     const format = "raw",         // keyData = new Uint8Array([23, 113, 57, 6, 35, -69, -60, 98, 84, -17, -125, -49, 18, 6, -92, 32]),         algorithm = "AES-GCM",         extractable = true,         usages = ["encrypt", "decrypt"];     // iv = new Uint8Array([47, 46, 123, 78, 36, 14, 109, 50, 121, 64, 11, 38]);     window.crypto.subtle.importKey(         format,         keyData,         algorithm,         extractable, usages     ).then(key =gt; {         window.crypto.subtle.encrypt({                 name: algorithm,                 iv: iv             },             key,             data         ).then(result =gt; {             console.log(Array.from(new Uint8Array((result))))         })     }) } console.log(___crypto__test(             new Uint8Array([23, 113, 57, 6, 35, -69, -60, 98, 84, -17, -125, -49, 18, 6, -92, 32]),                 new Uint8Array([47, 46, 123, 78, 36, 14, 109, 50, 121, 64, 11, 38]),             new Uint8Array([50, 49, 48]) )) crypto主要相关接口介绍 crypto.subtle.importKey const result = crypto.subtle.importKey(     format,     keyData,     algorithm,     extractable,     usages ); format  是一个字符串,描述要导入的密钥的数据格式。可以是以下之一:----------raw:原始格式。----------pkcs8:PKCS#8格式。----------spki:SubjectPublicKeyInfo格式。----------jwk:JSON Web密钥格式。 - keyData 是ArrayBuffer,TypedArray,a DataView或JSONWebKey包含给定格式的键的对象。 - algorithm  是一个字典对象,用于定义要导入的密钥的类型并提供额外的算法特定参数。对于RSASSA-PKCS1-v1_5,  RSA-PSS或  RSA-OAEP:传递RsaHashedImportParams对象。对于ECDSA或ECDH:传递  EcKeyImportParams对象。对于HMAC:传递一个HmacImportParams对象。对于AES-CTR,AES-CBC,AES-GCM或AES-KW:传递标识算法的字符串或形式为的对象{ "name": ALGORITHM },其中ALGORITHM 是算法的名称。对于PBKDF2  :传递字符串PBKDF2。 - extractable 是Boolean表明它是否将有可能使用到导出密钥SubtleCrypto.exportKey()或SubtleCrypto.wrapKey()。 - ke

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值