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

Python读取Chrome密码时CryptProtectData报错87的解决方法咨询

报错原因

这个报错触发在win32crypt.CryptUnprotectData(pwd)调用阶段,核心原因有3个:

  1. Chrome 80及以上版本已经弃用了原生DPAPI加密密码,改为AES-256-GCM加密,密钥单独存放在Local State配置文件中,旧解密逻辑直接调用CryptUnprotectData会识别密码密文格式错误,抛出参数异常
  2. 运行脚本时Chrome处于运行状态,会对Login Data数据库加独占锁,导致读取到的password_value字段残缺,传入解密函数参数不合法
  3. 当前Windows登录账号和保存Chrome密码时的账号不一致,DPAPI加密绑定用户上下文,跨用户解密会报错
解决方案
  • 第一步:运行脚本前完全关闭Chrome,打开任务管理器结束所有chrome.exe后台进程,解除数据库占用
  • 第二步:安装加密依赖库,执行命令:pip install pycryptodome
  • 第三步:替换为适配新版Chrome加密逻辑的代码,完整可运行代码如下:
import os
import sqlite3
import win32crypt
import json
import base64
from Crypto.Cipher import AES

def get_chrome():
    # 读取Chrome加密密钥
    local_state_path = os.path.expanduser('~') + r'\AppData\Local\Google\Chrome\User Data\Local State'
    with open(local_state_path, 'r', encoding='utf-8') as f:
        local_state = json.loads(f.read())
    encrypted_key = base64.b64decode(local_state['os_crypt']['encrypted_key'])
    # 去掉开头的DPAPI标识前缀
    encrypted_key = encrypted_key[5:]
    # 解密得到AES密钥
    key = win32crypt.CryptUnprotectData(encrypted_key, None, None, None, 0)[1]

    # 复制登录凭证数据库避免占用报错
    data_path = os.path.expanduser('~') + r'\AppData\Local\Google\Chrome\User Data\Default\Login Data'
    temp_db_path = 'temp_login_data.db'
    with open(data_path, 'rb') as f_in, open(temp_db_path, 'wb') as f_out:
        f_out.write(f_in.read())
    c = sqlite3.connect(temp_db_path)
    cursor = c.cursor()
    select_statement = 'SELECT origin_url, username_value, password_value FROM logins'
    cursor.execute(select_statement)
    login_data = cursor.fetchall()
    c.close()
    os.remove(temp_db_path)

    # 解密密码并写入文件
    filename = 'chromeData.csv'
    with open(filename, "w+", encoding='utf-8') as f:
        headers = "links, username, password\n"
        f.write(headers)
        for url, user_name, pwd in login_data:
            # 提取加密参数:去掉v10/v11标识头,取12位IV
            iv = pwd[3:15]
            encrypted_pwd = pwd[15:-16]
            cipher = AES.new(key, AES.MODE_GCM, iv)
            decrypted_pwd = cipher.decrypt(encrypted_pwd).decode('utf-8')
            line = f'{url}, {user_name}, {decrypted_pwd}\n'
            f.write(line)

    # 自动匹配火狐配置文件夹,无需手动修改路径
    firefox_profile_dir = os.path.expanduser('~') + r'\AppData\Roaming\Mozilla\Firefox\Profiles'
    src = ''
    for profile in os.listdir(firefox_profile_dir):
        if profile.endswith('.default-release') or profile.endswith('.default'):
            src = os.path.join(firefox_profile_dir, profile, 'logins.json')
            break
    with open(src, encoding='utf-8') as fd:
        df = json.load(fd)

    filename2 = 'firefox.csv'
    with open(filename2, "w+", encoding='utf-8') as fd:
        headers = "hostname,encryptedPass, encryptedUser\n"
        fd.write(headers)
        for each in df['logins']:
            a = each['hostname']
            b = each['encryptedPassword']
            c = each['encryptedUsername']
            fd.write(f'{a},{b},{c}\n')

if __name__=='__main__':
    get_chrome()
  • 若修改后仍然报错,检查是否使用微软账户切换登录Windows,改用本地账户登录后再运行脚本即可。

内容的提问来源于stack exchange,提问作者MaJoR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 08:15:04