Crypto++传递std::string格式IV解密出现PKCS#7块填充错误怎么解决
问题根因
- 核心错误:解密时仅对IV做了Hex解码,拿到的
encMessage仍然是Hex编码后的字符串,没有做解码就直接传入AES解密过滤器,导致输入的密文本身就是错误的,解密后的数据不符合PKCS#7填充规则,直接抛出校验错误。 - 次要问题1:你使用的密钥字符串
UltraSecretKeyPhrase长度不符合AES规范要求,AES密钥必须为16字节(AES-128)、24字节(AES-192)、32字节(AES-256),非标准长度会导致Crypto++内部自动截断,存在不可预期的行为。 - 次要问题2:
decc函数匹配不到::分隔符时返回NULL,与返回值类型std::string不匹配,会触发运行时异常。
修复代码
你只需要在解密环节给encMessage增加Hex解码步骤即可,以下是完整修正代码:
#include <crypto++/aes.h> #include <crypto++/modes.h> #include <crypto++/filters.h> #include <crypto++/osrng.h> #include <crypto++/hex.h> #include <iostream> using namespace std; using namespace CryptoPP; string encc(string plain) { AutoSeededRandomPool prng; SecByteBlock iv(AES::BLOCKSIZE); // 密钥调整为32字节适配AES-256,你也可以用哈希函数从任意长度口令派生固定长度密钥 std::string sKey = "UltraSecretKeyPhrase1234567890"; SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size()); prng.GenerateBlock(iv, iv.size()); std::string cipher, recovered; try { CBC_Mode< AES >::Encryption e; e.SetKeyWithIV(key, key.size(), iv); StringSource s(plain, true, new StreamTransformationFilter(e, new StringSink(cipher) ) ); } catch (const Exception& e) { cerr << e.what() << endl; exit(1); } string ciphertxt, ivString; HexEncoder encoder; encoder.Attach(new StringSink(ivString)); encoder.Put(iv, iv.size()); encoder.MessageEnd(); encoder.Attach(new StringSink(ciphertxt)); encoder.Put((const byte*)&cipher[0], cipher.size()); encoder.MessageEnd(); string toSend = ivString + "::" + ciphertxt; return toSend; } string decc(string toDec) { std::string sKey = "UltraSecretKeyPhrase1234567890"; SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size()); std::string recovered; string str1 = "::"; size_t found = toDec.find(str1); if (found != string::npos) { std::string sIv = toDec.substr(0, found); std::string encMessage = toDec.substr(found + 2, toDec.length()); // 解码IV string iv; HexDecoder decoder; decoder.Attach(new StringSink(iv)); decoder.Put((byte*)sIv.data(), sIv.size()); decoder.MessageEnd(); // 新增:对Hex编码的密文做解码 string decodedCipher; HexDecoder cipherDecoder; cipherDecoder.Attach(new StringSink(decodedCipher)); cipherDecoder.Put((byte*)encMessage.data(), encMessage.size()); cipherDecoder.MessageEnd(); try { CBC_Mode< AES >::Decryption d; d.SetKeyWithIV(key.data(), key.size(), (byte *)iv.data(), AES::BLOCKSIZE); // 传入解码后的二进制密文而非原始Hex字符串 StringSource s(decodedCipher, true, new StreamTransformationFilter(d, new StringSink(recovered) ) ); return recovered; } catch (const Exception& e) { std::cerr << e.what() << std::endl; exit(1); } } else return ""; } int main(){ string hh = encc("this is encoded"); cout << hh << endl; string gg = decc(hh); cout << gg << endl; return 0; }
内容的提问来源于stack exchange,提问作者Comet
相关产品推荐
相关产品推荐

