如何在Python提取 Chrome 密码?
在本文中,我们将讨论如何提取存储在 Chrome 浏览器中的所有密码。
注意:本文适用于在 Windows 上使用 Chrome 的用户。如果您是 Mac 或 Linux 用户,您可能需要对给定的路径进行一些更改,而Python程序的其余部分将保持不变。
安装:
现在,让我们安装一些重要的库,我们需要编写一个Python程序来提取Chrome密码。
pip install pycryptodome
pip install pypiwin32
在我们直接从 Chrome 中提取密码之前,我们需要定义一些有用的函数来帮助我们的主要功能。
- 第一个函数
def chrome_date_and_time(chrome_data):
# Chrome_data format is
# year-month-date hr:mins:seconds.milliseconds
# This will return datetime.datetime Object
return datetime(1601, 1, 1) + timedelta(microseconds=chrome_data)
chrome_date_and_time()函数负责将 Chrome 的日期格式转换为人类可读的日期和时间格式。
Chrome 日期和时间格式如下所示:
'year-month-date hr:mins:seconds.milliseconds'
示例:
2020-06-01 10:49:01.824691
- 第二个函数
def fetching_encryption_key():
# Local_computer_directory_path will
# look like this below
# C: => Users => => AppData =>
# Local => Google => Chrome => User Data =>
# Local State
local_computer_directory_path = os.path.join(
os.environ["USERPROFILE"], "AppData", "Local", "Google",
"Chrome", "User Data", "Local State")
with open(local_computer_directory_path, "r", encoding="utf-8") as f:
local_state_data = f.read()
local_state_data = json.loads(local_state_data)
# decoding the encryption key using base64
encryption_key = base64.b64decode(
local_state_data["os_crypt"]["encrypted_key"])
# remove Windows Data Protection API (DPAPI) str
encryption_key = encryption_key[5:]
# return decrypted key
return win32crypt.CryptUnprotectData(
encryption_key, None, None, None, 0)[1]
fetching_encryption_key()函数获取并解码用于加密密码的 AES 密钥。它以 JSON 文件的形式保存在“C:\Users\
- 第三函数
def password_decryption(password, encryption_key):
try:
iv = password[3:15]
password = password[15:]
# generate cipher
cipher = AES.new(encryption_key, AES.MODE_GCM, iv)
# decrypt password
return cipher.decrypt(password)[:-16].decode()
except:
try:
return str(win32crypt.CryptUnprotectData(password, None, None, None, 0)[1])
except:
return "No Passwords"
password_decryption()将加密后的密码和 AES 密钥作为参数,并返回密码的解密版本或人类可读格式。
下面是实现。
Python3
import os
import json
import base64
import sqlite3
import win32crypt
from Cryptodome.Cipher import AES
import shutil
from datetime import timezone, datetime, timedelta
def chrome_date_and_time(chrome_data):
# Chrome_data format is 'year-month-date
# hr:mins:seconds.milliseconds
# This will return datetime.datetime Object
return datetime(1601, 1, 1) + timedelta(microseconds=chrome_data)
def fetching_encryption_key():
# Local_computer_directory_path will look
# like this below
# C: => Users => => AppData =>
# Local => Google => Chrome => User Data =>
# Local State
local_computer_directory_path = os.path.join(
os.environ["USERPROFILE"], "AppData", "Local", "Google", "Chrome",
"User Data", "Local State")
with open(local_computer_directory_path, "r", encoding="utf-8") as f:
local_state_data = f.read()
local_state_data = json.loads(local_state_data)
# decoding the encryption key using base64
encryption_key = base64.b64decode(
local_state_data["os_crypt"]["encrypted_key"])
# remove Windows Data Protection API (DPAPI) str
encryption_key = encryption_key[5:]
# return decrypted key
return win32crypt.CryptUnprotectData(encryption_key, None, None, None, 0)[1]
def password_decryption(password, encryption_key):
try:
iv = password[3:15]
password = password[15:]
# generate cipher
cipher = AES.new(encryption_key, AES.MODE_GCM, iv)
# decrypt password
return cipher.decrypt(password)[:-16].decode()
except:
try:
return str(win32crypt.CryptUnprotectData(password, None, None, None, 0)[1])
except:
return "No Passwords"
def main():
key = fetching_encryption_key()
db_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local",
"Google", "Chrome", "User Data", "default", "Login Data")
filename = "ChromePasswords.db"
shutil.copyfile(db_path, filename)
# connecting to the database
db = sqlite3.connect(filename)
cursor = db.cursor()
# 'logins' table has the data
cursor.execute(
"select origin_url, action_url, username_value, password_value, date_created, date_last_used from logins "
"order by date_last_used")
# iterate over all rows
for row in cursor.fetchall():
main_url = row[0]
login_page_url = row[1]
user_name = row[2]
decrypted_password = password_decryption(row[3], key)
date_of_creation = row[4]
last_usuage = row[5]
if user_name or decrypted_password:
print(f"Main URL: {main_url}")
print(f"Login URL: {login_page_url}")
print(f"User name: {user_name}")
print(f"Decrypted Password: {decrypted_password}")
else:
continue
if date_of_creation != 86400000000 and date_of_creation:
print(f"Creation date: {str(chrome_date_and_time(date_of_creation))}")
if last_usuage != 86400000000 and last_usuage:
print(f"Last Used: {str(chrome_date_and_time(last_usuage))}")
print("=" * 100)
cursor.close()
db.close()
try:
# trying to remove the copied db file as
# well from local computer
os.remove(filename)
except:
pass
if __name__ == "__main__":
main()
输出:
对于上面的代码,我们遵循以下步骤;
- 首先,我们使用之前定义的函数fetching_encryption_key()来获取加密密钥
- 然后将SQLite数据库复制到“C:\Users\
\AppData\Local\Google\Chrome\User Data\default\Login Data ”中保存的当前目录的密码数据,并建立连接。这是因为 Chrome 启动时原始数据库文件被锁定。 - 在游标对象的帮助下,我们将按照 date_last_used从'logins'表顺序执行 SELECT SQL 查询。
- 以更易读的格式遍历所有登录行以获取每个密码和格式 date_created 和 date_last_used 的密码。
- 最后,借助打印语句,我们将打印从 Chrome 中提取的所有已保存凭据。
- 从当前目录中删除数据库的副本。