You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法解密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标签传入解密器进行验证,导致认证失败解密失败。

其他问题点

  1. 异常捕获范围:Exception需指定CryptoPP::命名空间,否则无法捕获Crypto++库抛出的异常。
  2. 提前resize解密缓冲区:StringSink会自动管理输出字符串大小,提前resize可能导致解密后出现多余空字节。
  3. 密钥长度校验:需确保传入的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:45:33