如何使用 Python 将 SQLite Blob 字段转换为字符串
How to convert SQLite Blob field to string with Python
我想打开 Chrome(登录数据)文件并使用其密码字段。但是这个字段是以byte/blob方式存储的,不能转成文本
我也尝试了 codecs 和 pickle 以及 bytes.encode 和 str.decode 但它没有用。
请查看下面的代码并提供帮助:
import sqlite3
connection_obj = sqlite3.connect('C:/Users/{username}/AppData/Local/Google/Chrome/User
Data/Default/Login Data')
cursor_obj = connection_obj.cursor()
statement = '''SELECT action_url, username_value, password_value FROM logins'''
cursor_obj.execute(statement)
output = cursor_obj.fetchmany(5)
for url,usr,psw in output:
# convert psw blob -> ascii text
# ....
# ....
# for example psw filed:
# b'v10\x7f\xa3\x1a\xd1\x83g\x8c\xc4\x14]\xb6n\xf85\xba\xca\xf5r\x17\xb6D\xed\xf5\x11rM\xbe\xbf\xb1\xc2y\xc5Vr\xc3\xb3NB\xc7J\x14\x95'
#
# convert to below text :
# zarfilm-136342
print(url, usr, psw,sep='------')
print('*'*10)
connection_obj.commit()
connection_obj.close()
得知此字段已加密,您感到惊讶吗?如果不是,Google 将会陷入麻烦的世界。甚至 Chrome 也不知道如何解密。它是通过 Windows 加密 API 完成的,并且涉及到您的 Windows 登录密码。你无法得到它们。
该数据在 AES 中加密,并且进一步使用 CryptProtectData 加密密钥以将加密密钥锁定到用户数据。你可以用这样的东西解密数据:
import base64, json, os, sqlite3, win32crypt
from Crypto.Cipher import AES
def chrome_key():
local_state_fn = os.path.join(os.environ["USERPROFILE"],"AppData","Local","Google","Chrome","User Data","Local State")
with open(local_state_fn, "r") as f:
local_state = json.load(f)
key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
key = key[5:]
return win32crypt.CryptUnprotectData(key, None, None, None, 0)[1]
def decrypt_password(password, key):
iv, password = password[3:15], password[15:]
aes = AES.new(key, AES.MODE_GCM, iv)
return aes.decrypt(password)[:-16].decode("utf-8")
def main():
key = chrome_key()
db_fn = os.path.join(os.environ["USERPROFILE"],"AppData","Local","Google","Chrome","User Data","default","Login Data")
db = sqlite3.connect(db_fn)
for origin_url, username, password_crypt in db.execute("SELECT origin_url, username_value, password_value FROM logins;"):
password = decrypt_password(password_crypt, key)
print(f"{origin_url}, {username}, {password}")
db.close()
if __name__ == "__main__":
main()
我想打开 Chrome(登录数据)文件并使用其密码字段。但是这个字段是以byte/blob方式存储的,不能转成文本
我也尝试了 codecs 和 pickle 以及 bytes.encode 和 str.decode 但它没有用。 请查看下面的代码并提供帮助:
import sqlite3
connection_obj = sqlite3.connect('C:/Users/{username}/AppData/Local/Google/Chrome/User
Data/Default/Login Data')
cursor_obj = connection_obj.cursor()
statement = '''SELECT action_url, username_value, password_value FROM logins'''
cursor_obj.execute(statement)
output = cursor_obj.fetchmany(5)
for url,usr,psw in output:
# convert psw blob -> ascii text
# ....
# ....
# for example psw filed:
# b'v10\x7f\xa3\x1a\xd1\x83g\x8c\xc4\x14]\xb6n\xf85\xba\xca\xf5r\x17\xb6D\xed\xf5\x11rM\xbe\xbf\xb1\xc2y\xc5Vr\xc3\xb3NB\xc7J\x14\x95'
#
# convert to below text :
# zarfilm-136342
print(url, usr, psw,sep='------')
print('*'*10)
connection_obj.commit()
connection_obj.close()
得知此字段已加密,您感到惊讶吗?如果不是,Google 将会陷入麻烦的世界。甚至 Chrome 也不知道如何解密。它是通过 Windows 加密 API 完成的,并且涉及到您的 Windows 登录密码。你无法得到它们。
该数据在 AES 中加密,并且进一步使用 CryptProtectData 加密密钥以将加密密钥锁定到用户数据。你可以用这样的东西解密数据:
import base64, json, os, sqlite3, win32crypt
from Crypto.Cipher import AES
def chrome_key():
local_state_fn = os.path.join(os.environ["USERPROFILE"],"AppData","Local","Google","Chrome","User Data","Local State")
with open(local_state_fn, "r") as f:
local_state = json.load(f)
key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
key = key[5:]
return win32crypt.CryptUnprotectData(key, None, None, None, 0)[1]
def decrypt_password(password, key):
iv, password = password[3:15], password[15:]
aes = AES.new(key, AES.MODE_GCM, iv)
return aes.decrypt(password)[:-16].decode("utf-8")
def main():
key = chrome_key()
db_fn = os.path.join(os.environ["USERPROFILE"],"AppData","Local","Google","Chrome","User Data","default","Login Data")
db = sqlite3.connect(db_fn)
for origin_url, username, password_crypt in db.execute("SELECT origin_url, username_value, password_value FROM logins;"):
password = decrypt_password(password_crypt, key)
print(f"{origin_url}, {username}, {password}")
db.close()
if __name__ == "__main__":
main()