无法解密Chrome的Login Data密码——C++ Crypto++代码问题求助
Chrome密码解密C++代码修复(对比Python实现)
我用Crypto库编写了一段C代码,用于解密Chrome浏览器Login Data中的密码(仅作学习用途),但代码无法正常运行。同时附上Python中使用PyCryptodome库实现的对应逻辑片段,希望解决问题。
原C++代码
std::string decrypt_password(const std::string& ciphertext, const std::string& secret_key) { try { if (ciphertext.size() < 31) { std::cout << "[ERR] Invalid ciphertext format." << std::endl; return ""; } // Initialization vector for AES decryption std::vector<byte> initialization_vector(ciphertext.begin() + 3, ciphertext.begin() + 15); // Get encrypted password by removing suffix bytes (last 16 bytes) std::vector<byte> encrypted_password(ciphertext.begin() + 15, ciphertext.end() - 16); // Build the cipher to decrypt the ciphertext GCM<AES>::Decryption gcmDecryption; gcmDecryption.SetKeyWithIV(reinterpret_cast<const byte*>(secret_key.data()), CryptoPP::AES::DEFAULT_KEYLENGTH, initialization_vector.data(), initialization_vector.size()); // Create a buffer to hold the decrypted password std::string decrypted_password; decrypted_password.resize(encrypted_password.size()); // Resize the buffer to the correct size // Decrypt the password CryptoPP::AuthenticatedDecryptionFilter adf(gcmDecryption, new CryptoPP::StringSink(decrypted_password)); adf.Put(reinterpret_cast<const byte*>(encrypted_password.data()), encrypted_password.size()); adf.MessageEnd(); // Check if the authentication was successful if (!adf.GetLastResult()) { std::cout << "[ERR] Authentication failed. Unable to decrypt the password." << std::endl; return ""; } // Return the decrypted password return decrypted_password; } catch (const Exception& e) { std::cout << "[ERR] " << e.what() << std::endl; std::cout << "[ERR] Unable to decrypt, Chrome version <80 not supported. Please check." << std::endl; return ""; } }
Python实现片段
cipher = generate_cipher(secret_key, initialisation_vector) decrypted_pass = decrypt_payload(cipher, encrypted_password) decrypted_pass = decrypted_pass.decode()
问题分析与修复方案
核心问题:GCM标签未传入解密流程
Chrome的密码加密格式为:v10前缀(3字节) + 12字节IV + 密文 + 16字节GCM认证标签。原C++代码仅传入了密文,未将GCM标签传入解密器进行验证,导致认证失败解密失败。
其他问题点
- 异常捕获范围:
Exception需指定CryptoPP::命名空间,否则无法捕获Crypto++库抛出的异常。 - 提前resize解密缓冲区:
StringSink会自动管理输出字符串大小,提前resize可能导致解密后出现多余空字节。 - 密钥长度校验:需确保传入的
secret_key长度符合AES要求(16字节对应AES-128,Chrome 80+版本默认用AES-128-GCM)。
修复后的C++代码
#include <CryptoPP/aes.h> #include <CryptoPP/gcm.h> #include <CryptoPP/filters.h> #include <CryptoPP/strings.h> #include <vector> #include <string> #include <iostream> using namespace CryptoPP; std::string decrypt_password(const std::string& ciphertext, const std::string& secret_key) { try { // Chrome加密格式:3字节前缀(v10) + 12字节IV + 密文 + 16字节GCM标签 if (ciphertext.size() < 3 + 12 + 1 + 16) { // 最小长度:前缀+IV+1字节密文+标签 std::cout << "[ERR] Invalid ciphertext format." << std::endl; return ""; } // 提取12字节IV(前缀后开始) std::vector<byte> iv(ciphertext.begin() + 3, ciphertext.begin() + 3 + 12); // 提取密文(IV后到标签前) std::vector<byte> cipher_data(ciphertext.begin() + 3 + 12, ciphertext.end() - 16); // 提取16字节GCM标签 std::vector<byte> tag(ciphertext.end() - 16, ciphertext.end()); // 初始化GCM解密器 GCM<AES>::Decryption gcmDecryption; // 密钥长度需与实际一致,Chrome 80+用16字节(AES-128) if (secret_key.size() != AES::DEFAULT_KEYLENGTH) { std::cout << "[ERR] Invalid secret key length." << std::endl; return ""; } gcmDecryption.SetKeyWithIV(reinterpret_cast<const byte*>(secret_key.data()), secret_key.size(), iv.data(), iv.size()); // 处理解密与认证 std::string decrypted_password; AuthenticatedDecryptionFilter adf( gcmDecryption, new StringSink(decrypted_password), AuthenticatedDecryptionFilter::DEFAULT_FLAGS ); // 传入密文数据 adf.Put(cipher_data.data(), cipher_data.size()); // 设置GCM认证标签 adf.SetTag(tag.data(), tag.size()); // 结束解密流程 adf.MessageEnd(); // 验证认证结果 if (!adf.GetLastResult()) { std::cout << "[ERR] Authentication failed. Unable to decrypt the password." << std::endl; return ""; } return decrypted_password; } catch (const CryptoPP::Exception& e) { std::cout << "[ERR] " << e.what() << std::endl; std::cout << "[ERR] Unable to decrypt, Chrome version <80 not supported. Please check." << std::endl; return ""; } }
与Python逻辑对齐说明
Python代码中的decrypt_payload本质是调用了PyCryptodome的decrypt_and_verify方法,该方法会同时处理密文和标签。修复后的C++代码通过SetTag传入标签,与Python逻辑完全对齐,确保解密流程一致。
内容的提问来源于stack exchange,提问作者Jackie
相关产品推荐
相关产品推荐

