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

Linux下Python解密Chromium 103 Cookie触发UTF-8解码错误

问题原因

解密失败是旧教程逻辑和新版本Chromium加密机制不匹配导致的,核心问题有两个:

  • 加密版本不匹配:你所用的Chromium 103内核版本已经将Cookie加密方案升级为v11版本,从运行日志打印的加密值前缀b'v11'即可确认。原有针对v10版本的AES-CBC解密逻辑完全不兼容v11的加密结构,强行解密得到的只能是乱码,自然会触发UTF-8解码错误。
  • 密钥派生逻辑过时:旧教程中Linux环境硬编码加密密码为peanuts直接派生密钥解密Cookie的逻辑已经废弃。新版本Chromium系浏览器(包括Brave)会随机生成独立的加密主密钥,存储在配置目录的Local State文件中,主密钥本身通过系统密钥环(GNOME Keyring/KWallet)加密后存储,不存在可以直接用来解密Cookie的固定硬编码密码。
v11加密值结构

v11版本的加密Cookie结构和v10完全不同,拆分规则如下:

  • 前3字节:固定版本前缀v11
  • 接下来12字节:AES-GCM加密模式使用的Nonce值
  • 剩余部分:Cookie密文 + 末尾16字节的GCM认证标签
修复步骤
  • 安装所需依赖:
    pip install pycryptodome keyring
  • 运行代码前完全关闭Brave浏览器,避免Cookie数据库被进程锁定无法读取;如果不想关闭浏览器,可以先将Cookies文件复制到其他路径,修改代码里的数据库路径为复制后的文件路径即可。
修复后兼容v10/v11的代码
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
import sqlite3
import base64
import json
import os

# 配置项
BRAVE_CONFIG_ROOT = '/home/hasan/.config/BraveSoftware/Brave-Browser/Default'
COOKIE_DB_PATH = os.path.join(BRAVE_CONFIG_ROOT, 'Cookies')
TARGET_COOKIE_NAME = 'cf_clearance'

def clean_pkcs7(x):
    # 处理PKCS7填充,仅v10版本需要
    return x[:-x[-1]].decode('utf8')

def get_encryption_key():
    # 从Local State读取并解密主密钥
    local_state_path = os.path.join(os.path.dirname(BRAVE_CONFIG_ROOT), 'Local State')
    with open(local_state_path, 'r', encoding='utf-8') as f:
        local_state = json.load(f)
    
    # 解析加密的主密钥
    encrypted_key = base64.b64decode(local_state['os_crypt']['encrypted_key'])
    encrypted_key = encrypted_key[5:]  # 去掉开头固定的DPAPI标识

    # 获取密钥环密码,优先读系统密钥环,失败则回退到默认值peanuts
    try:
        import keyring
        keyring_pass = keyring.get_password('Brave Safe Storage', 'Brave')
        if not keyring_pass:
            keyring_pass = 'peanuts'
    except Exception:
        keyring_pass = 'peanuts'
    keyring_pass = keyring_pass.encode('utf8')

    # 派生密钥解密主密钥
    kdf_salt = b'saltysalt'
    kdf_iter = 1
    kdf_key_len = 16
    kdf_key = PBKDF2(keyring_pass, kdf_salt, kdf_key_len, kdf_iter)
    cipher = AES.new(kdf_key, AES.MODE_CBC, IV=b' '*16)
    decrypted_key = cipher.decrypt(encrypted_key)
    # 去掉主密钥的PKCS7填充
    decrypted_key = decrypted_key[:-decrypted_key[-1]]
    return decrypted_key

def decrypt_cookie_value(encrypted_value, key):
    # 按版本前缀走不同解密逻辑
    if encrypted_value[:3] == b'v10':
        # 老版本v10逻辑
        encrypted_value = encrypted_value[3:]
        cipher = AES.new(key, AES.MODE_CBC, IV=b' '*16)
        decrypted = cipher.decrypt(encrypted_value)
        return clean_pkcs7(decrypted)
    elif encrypted_value[:3] == b'v11':
        # 新版本v11逻辑
        nonce = encrypted_value[3:15]
        ciphertext = encrypted_value[15:]
        cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
        # decrypt_and_verify会自动校验认证标签,防止篡改
        decrypted = cipher.decrypt_and_verify(ciphertext[:-16], ciphertext[-16:])
        return decrypted.decode('utf8')
    else:
        raise ValueError(f'不支持的加密版本: {encrypted_value[:3]}')

def get_target_cookie_encrypted():
    db = sqlite3.connect(COOKIE_DB_PATH)
    cursor = db.cursor()
    cursor.execute(f'SELECT encrypted_value FROM cookies WHERE name = "{TARGET_COOKIE_NAME}";')
    res = cursor.fetchone()
    db.close()
    if not res:
        raise ValueError('未找到对应Cookie')
    return res[0]

if __name__ == '__main__':
    master_key = get_encryption_key()
    encrypted_val = get_target_cookie_encrypted()
    plain_cookie = decrypt_cookie_value(encrypted_val, master_key)
    print(f'解密后的Cookie值: {plain_cookie}')

常见问题说明:如果运行时提示密钥环权限错误,可以先在终端执行secret-tool lookup application brave确认密钥环访问正常,大部分个人桌面环境默认配置下直接运行代码即可正常解密。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 04:39:21