Chrome 80 如何解码 Cookie

Chrome 80 how to decode cookies

提问人:Pavel Kaigorodov 提问时间:2/26/2020 最后编辑:Pavel Kaigorodov 更新时间:7/6/2020 访问量:30899

问:

我有一个用于打开和解密 Google Chrome cookie 的工作脚本,如下所示:

decrypted = win32crypt.CryptUnprotectData(enctypted_cookie_value, None, None, None, 0)

似乎在更新 80 之后,它不再是一个有效的解决方案。

根据这篇博文 https://blog.nirsoft.net/2020/02/19/tools-update-new-encryption-chrome-chromium-version-80/ 我似乎需要从本地状态文件encrypted_key CryptUnprotectData,而不是使用解密的密钥以某种方式解密 cookie。

对于第一部分,我得到了我的encrypted_key

path = r'%LocalAppData%\Google\Chrome\User Data\Local State'
path = os.path.expandvars(path)
with open(path, 'r') as file:
    encrypted_key = json.loads(file.read())['os_crypt']['encrypted_key']
encrypted_key = bytearray(encrypted_key, 'utf-8')

然后我试图解密它

decrypted_key = win32crypt。CryptUnprotectData(encrypted_key、无、无、无、0)

并得到了例外:

pywintypes.error: (13, 'CryptProtectData', 'The data is invalid.')

我不知道如何解决它

同样对于加密的第二部分,似乎我应该使用 pycryptodome,类似于以下代码片段:

cipher = AES.new(encrypted_key, AES.MODE_GCM, nonce=nonce)
plaintext = cipher.decrypt(data)

但是我不知道我应该从哪里获得随机数值

有人可以解释一下,如何正确解密 Chrome cookie?

python google-chrome cookies aes dpapi

评论


答:

26赞 Topaco 2/27/2020 #1

从 Chrome 版本 80 及更高版本开始,Cookie 在 GCM 模式下使用 AES-256 进行加密。应用的密钥使用 DPAPI 进行加密。有关详细信息,请参阅此处的 Chrome v80.0 及更高版本部分

加密密钥以 (即 ) 的 ASCII 编码开头,并且是 Base64 编码的,即密钥必须首先进行 Base64 解码,并且必须删除前 5 个字节。之后,可以进行解密。解密返回一个元组,其第二个值包含解密的密钥:DPAPI0x4450415049win32crypt.CryptUnprotectData

import os
import json
import base64 
import win32crypt
from Crypto.Cipher import AES

path = r'%LocalAppData%\Google\Chrome\User Data\Local State'
path = os.path.expandvars(path)
with open(path, 'r') as file:
    encrypted_key = json.loads(file.read())['os_crypt']['encrypted_key']
encrypted_key = base64.b64decode(encrypted_key)                                       # Base64 decoding
encrypted_key = encrypted_key[5:]                                                     # Remove DPAPI
decrypted_key = win32crypt.CryptUnprotectData(encrypted_key, None, None, None, 0)[1]  # Decrypt key

Cookie 的加密是在 GCM 模式下使用 AES-256 执行的。这是经过身份验证的加密,可保证机密性和真实性/完整性。在加密过程中,会生成一个身份验证标签,用于解密过程中的完整性验证。GCM 模式基于 CTR 模式,并使用 IV(随机数)。除了 32 字节密钥外,解密还需要随机数和身份验证标记。

加密数据以 (即 )的 ASCII 编码开始,然后是 12 字节的随机数、实际的密文,最后是 16 字节的身份验证标记。各个组件可以按如下方式分离:v100x763130

data = bytes.fromhex('763130...') # the encrypted cookie
nonce = data[3:3+12]
ciphertext = data[3+12:-16]
tag = data[-16:]

从而包含加密数据。解密本身是使用 PyCryptodome 完成的,具有:data

cipher = AES.new(decrypted_key, AES.MODE_GCM, nonce=nonce)
plaintext = cipher.decrypt_and_verify(ciphertext, tag) # the decrypted cookie

注意:通常,还会存储一些 Cookie,这些 Cookie 已与低于 v80 的 Chrome 版本一起保存,因此是 DPAPI 加密的。DPAPI 加密的 cookie 可以通过以下事实来识别:序列 ,这里 和 这里, 关于 DPAPI 部分当然,这些 cookie 不能如上所述解密,但可以使用 DPAPI 加密 cookie 的前一个过程进行解密。以未加密或加密形式查看 Cookie 的工具分别是 ChromeCookiesViewDB Browser for SQLite0x01000000D08C9DDF0115D1118C7A00C04FC297EB

评论

1赞 Pavel Kaigorodov 2/27/2020
您的解决方案正在发挥作用,非常感谢!就我而言,我删除了“data = bytes.fromhex('763130...')# 加密的 cookie“部分,因为从 sqlite3 游标接收到的加密 cookie 已经是字节类型了
2赞 evandrix 5/8/2020
而不是 ,你可以简单地做json.loads(file.read())json.load(file)
0赞 Cenk Ten 4/20/2021
有没有 Linux 的替代品?
1赞 Topaco 4/20/2021
@CenkTen - 我不知道。如果需要,您应该在 SO 上发布有关此的问题。
1赞 JellicleCat 2/19/2022
@CenkTen这里有一个 Linux 的答案:stackoverflow.com/a/23727331/507721
-1赞 dgrandm 2/27/2020 #2

您可能已从 Windows 上的一个用户帐户复制了 DPAPI 加密密钥值,并尝试在以其他用户身份登录时调用 CryptUnprotectData WinAPI。根据 DPAPI 的性质,这是行不通的。