📜  如何在Python提取 Chrome 密码?

📅  最后修改于: 2022-05-13 01:54:39.611000             🧑  作者: Mango

如何在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\\AppData\Local\Google\Chrome\User Data\Local State”中。此函数对加密密钥很有用。

  • 第三函数
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 中提取的所有已保存凭据。
  • 从当前目录中删除数据库的副本。