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
相关产品推荐
相关产品推荐

