AES-CBC解密:JS转C++实现遇阻,求解决方案
AES-CBC解密问题的修复方案
你的C++代码无法正常解密,核心原因是完全没有对齐CryptoJS的密钥/IV派生逻辑,和是否改用OpenSSL无关。先明确CryptoJS的真实解密流程:
- 传入的
key.toString()是SHA512哈希字符串,作为密码而非直接的AES密钥 - CryptoJS通过**EvpKDF(即PBKDF2-HMAC-SHA1)**从该密码派生AES密钥和IV,参数为:迭代次数10000,派生总长度为32字节(AES密钥)+16字节(IV)=48字节
- 密文是Base64格式,需先解码为字节流再解密
修正后的CryptoPP实现
以下是对齐CryptoJS逻辑的C++代码:
1. Base64解码函数
#include <cryptopp/base64.h> #include <cryptopp/filters.h> #include <cryptopp/strings.h> std::string base64Decode(const std::string& encoded) { std::string decoded; CryptoPP::StringSource ss(encoded, true, new CryptoPP::Base64Decoder( new CryptoPP::StringSink(decoded) ) ); return decoded; }
2. 完整解密函数
#include <cryptopp/aes.h> #include <cryptopp/cbc.h> #include <cryptopp/pwdbased.h> #include <cryptopp/sha.h> std::string decrypt(const std::string& base64Message, const std::string& password) { // 1. 解码Base64密文 std::string ciphertext = base64Decode(base64Message); // 2. PBKDF2-HMAC-SHA1派生密钥和IV byte derived[48]; CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA1> pbkdf2; pbkdf2.DeriveKey(derived, sizeof(derived), 0, reinterpret_cast<const byte*>(password.data()), password.size(), nullptr, 0, // 空盐,对齐CryptoJS默认行为 10000 // 迭代次数 ); std::string aesKey(reinterpret_cast<char*>(derived), 32); std::string iv(reinterpret_cast<char*>(derived + 32), 16); // 3. AES-CBC解密 std::string decrypted; CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption aesDecrypt; aesDecrypt.SetKeyWithIV(reinterpret_cast<const byte*>(aesKey.data()), aesKey.size(), reinterpret_cast<const byte*>(iv.data()), iv.size()); CryptoPP::StringSource ss(ciphertext, true, new CryptoPP::StreamTransformationFilter(aesDecrypt, new CryptoPP::StringSink(decrypted) ) ); return decrypted; }
是否需要改用OpenSSL?
完全没必要,CryptoPP已经能完美实现需求。如果一定要用OpenSSL,逻辑完全一致:先Base64解码,再用PKCS5_PBKDF2_HMAC_SHA1派生密钥和IV,最后执行AES-CBC解密。
内容的提问来源于stack exchange,提问作者DreamCoder
相关产品推荐
相关产品推荐

