解密Chromium Cookie
我想在Python中使用Chromium的cookies,因为Chromium用AES(带有CBC模式)加密它的cookies,我需要破解这个加密。
我可以从OS X的钥匙串中找回AES密钥(它是以Base 64格式存储的):
security find-generic-password -w -a Chrome -s Chrome Safe Storage
# From Python:
python -c 'from subprocess import PIPE, Popen; print(Popen(['security', 'find-generic-password', '-w', '-a', 'Chrome', '-s', 'Chrome Safe Storage'], stdout=PIPE).stdout.read().strip())'
这是我现在有的代码,缺少的就是解密cookies的部分:
from subprocess import PIPE, Popen
from sqlite3 import dbapi2
def get_encryption_key():
cmd = ['security', 'find-generic-password', '-w', '-a', 'Chrome', '-s', 'Chrome Safe Storage']
return Popen(cmd, stdout=PIPE).stdout.read().strip().decode('base-64')
def get_cookies(database):
key = get_encryption_key()
with dbapi2.connect(database) as conn:
conn.rollback()
rows = conn.cursor().execute('SELECT name, encrypted_value FROM cookies WHERE host_key like ".example.com"')
cookies = {}
for name, enc_val in rows:
val = decrypt(enc_val, key) # magic missing
cookies[name] = val
return cookies
我尝试了很多方法,使用了pyCrypto的AES模块,但是:
- 我没有初始化向量(IV)
enc_val
的长度不是16的倍数
这里有一些看起来有用的链接:
你能帮我解决这个问题吗?
2 个回答
5
@n8henrie的回答对我有用,但在我的环境中,使用的是Ubuntu系统,Chrome浏览器不再用“peanuts”作为密码,而是把密码存储在gnome钥匙串里。我通过使用secretstorage这个包,成功获取了用于解密的密码,方法如下:
import secretstorage
bus = secretstorage.dbus_init()
collection = secretstorage.get_default_collection(bus)
for item in collection.get_all_items():
if item.get_label() == 'Chrome Safe Storage':
MY_PASS = item.get_secret()
break
else:
raise Exception('Chrome password not found!')
31
你走在正确的道路上!我花了几天时间在这个问题上,终于搞明白了。(非常感谢原作者提供的有用链接,指向Chromium的源代码。)
我写了一篇文章,里面有更多的细节和一个可以运行的脚本,不过这里我先给你讲讲基本的思路:
#! /usr/bin/env python3
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
# Function to get rid of padding
def clean(x):
return x[:-x[-1]].decode('utf8')
# replace with your encrypted_value from sqlite3
encrypted_value = ENCRYPTED_VALUE
# Trim off the 'v10' that Chrome/ium prepends
encrypted_value = encrypted_value[3:]
# Default values used by both Chrome and Chromium in OSX and Linux
salt = b'saltysalt'
iv = b' ' * 16
length = 16
# On Mac, replace MY_PASS with your password from Keychain
# On Linux, replace MY_PASS with 'peanuts'
my_pass = MY_PASS
my_pass = my_pass.encode('utf8')
# 1003 on Mac, 1 on Linux
iterations = 1003
key = PBKDF2(my_pass, salt, length, iterations)
cipher = AES.new(key, AES.MODE_CBC, IV=iv)
decrypted = cipher.decrypt(encrypted_value)
print(clean(decrypted))