How to Extract All Stored Chrome Passwords with Python?

By | November 13, 2021
How to Extract all stored Chrome Password with Python

This Python tutorial explains how to extract all stored Chrome password with Python. Chrome is a very powerful web browser. It provides a default password manager to generate and store passwords. The password manager store all the passwords in the cloud as well as in the user’s local system in an SQLite database. We can use the sqlite3 database and Chrome decrypt libraries to extract and decrypt the stored passwords.

Manually decrypting all the Chrome passwords can be a tedious task, but luckily with Python and a few lines of code, we can extract all the saved passwords from Chrome as well as all the other popular web browsers.

For this Python tutorial, we will be writing a Python script that can extract all the passwords stored in your Chrome browser. This Python tutorial is for those users who are using Chrome on the Windows operating system. If you are a macOS or Linux user, then you might have to make some changes in the specified path, but the rest of the Python program will stay the same.

How to Extract All Stored Chrome Password with Python?

To make this tutorial more legible, we have followed the modular approach in which we have divided the entire Python code into multiple functions. Before diving into the main code, we need to first install the dependencies or libraries we require for building the Python program that can extract all stored passwords in Chrome.

Install libraries

We need to install pycryptodome and pywin32 libraries to make the code work. Following are the pip commands to install them:

Vamware
pip install pycryptodome
pip install pypiwin32

Now open your favorite Python IDE or text editor and start coding. We will start with importing all the necessary modules at the top of our Python script.

#python standard modules
import os
import json
import base64
import sqlite3
import shutil
from datetime import timezone, datetime, timedelta

#3rd party modules
import win32crypt
from Crypto.Cipher import AES

As we have already mentioned, we will be wrapping our code around the functions. So, let’s define our first function, my_chrome_datetime(), which will convert Chrome time to a human-readable format.

Vamware

#function 1 my_chrome_datetime(time_in_mseconds)

def my_chrome_datetime(time_in_mseconds):
    return datetime(1601, 1, 1) + timedelta(microseconds=time_in_mseconds)

The my_chrome_datetime(time_in_mseconds) function accepts the time in microseconds because Chrome stores the time in timestamps format as base 1 Jan 1601. Next, let’s define the encryption_key()function. It will extract and decode the Chrome ASE key that was used to encrypt the passwords. The ASE key is located in the “Local State” file at the C:\Users\USER_Name\AppData\Local\Google\Chrome\User Data directory.

#function 2 encryption_key()

def encryption_key():

    #C:\Users\USER_Name\AppData\Local\Google\Chrome\Local State
    localState_path = os.path.join(os.environ["USERPROFILE"],
                                    "AppData", "Local", "Google", "Chrome",
                                    "User Data", "Local State")

    #read local state file
    with open(localState_path, "r", encoding="utf-8") as file:
        local_state_file = file.read()
        local_state_file = json.loads(local_state_file)

    # decode the key and remove first 5 DPAPI str characters
    ASE_key = base64.b64decode(local_state_file["os_crypt"]["encrypted_key"])[5:]

    return win32crypt.CryptUnprotectData(ASE_key, None, None, None, 0)[1]  # decryted key

Now we have the function for the encrypted key. Next, let’s define a function decrypt_password(enc_password, key) that will take the encrypted password and encrypted key as arguments and decode or decrypt the password in a human-readable format.

#function 3 decrypt_password(enc_password, key)

def decrypt_password(enc_password, key):
    try:

        init_vector = enc_password[3:15]
        enc_password = enc_password[15:]

        # initialize cipher object
        cipher = AES.new(key, AES.MODE_GCM, init_vector)
        # decrypt password
        return cipher.decrypt(enc_password)[:-16].decode()
    except:
        try:
            return str(win32crypt.CryptUnprotectData(password, None, None, None, 0)[1])
        except:
            return "No Passwords(logged in with Social Account)"

Now let’s create the main() function that will open the Passwords database to read the encrypted passwords, call the encryption_key() function to get the encryption key, and pass the password and encryption key to the decrypt_password() function to decode the password.

#function 4 main()

def main():

    # local passwords path
    password_db_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local",
                            "Google", "Chrome", "User Data", "Default", "Login Data")

    #copy the login data file to current directory as "my_chrome_data.db
    shutil.copyfile(password_db_path,"my_chrome_data.db")

    # connect to the database
    db = sqlite3.connect("my_chrome_data.db")
    cursor = db.cursor()

    # run the query
    cursor.execute("SELECT origin_url, username_value, password_value, date_created FROM logins")

    #get the encryption key
    encp_key = encryption_key()

    # iterate over all rows
    for row in cursor.fetchall():
        site_url = row[0]
        username = row[1]
        password = decrypt_password(row[2], encp_key)
        date_created = row[3]

        if username or password:
            print("Site Login URL:", site_url)
            print("Username/Email:", username)
            print(f"Password:",password)
        else:
            continue
        if date_created:
            print("Date date_created:", str(my_chrome_datetime(date_created)))
        print("\n|","-"*50, "|\n")

    cursor.close()
    db.close()

    #remove the copied database after reading passwords
    os.remove("my_chrome_data.db")

After defining the main() function, let’s call it with the if __name__==”__main__”  statement. Although we can also call the main function directly, using the aforementioned statement is a better option.

#call the main() function

if __name__ == "__main__":
    main()

How to Extract All Stored Chrome Password with Python? [The Code]

Finally, put all the code together and execute it.

#Python program to extract all the stored Chrome passwords
#python standard modules
import os
import json
import base64
import sqlite3
import shutil
from datetime import timezone, datetime, timedelta

#3rd party modules
import win32crypt
from Crypto.Cipher import AES

def my_chrome_datetime(time_in_mseconds):
    """Return a `datetime.datetime` object from a chrome format datetime
    Since `chromedate` is formatted as the number of microseconds since January, 1601"""
    return datetime(1601, 1, 1) + timedelta(microseconds=time_in_mseconds)

def encryption_key():

    #C:\Users\USER_Name\AppData\Local\Google\Chrome\Local State
    localState_path = os.path.join(os.environ["USERPROFILE"],
                                    "AppData", "Local", "Google", "Chrome",
                                    "User Data", "Local State")
    #read local state file
    with open(localState_path, "r", encoding="utf-8") as file:
        local_state_file = file.read()
        local_state_file = json.loads(local_state_file)

    # decode the key and remove first 5 DPAPI str characters
    ASE_key = base64.b64decode(local_state_file["os_crypt"]["encrypted_key"])[5:]

    return win32crypt.CryptUnprotectData(ASE_key, None, None, None, 0)[1]  # decryted key

def decrypt_password(enc_password, key):
    try:

        init_vector = enc_password[3:15]
        enc_password = enc_password[15:]

        # initialize cipher object
        cipher = AES.new(key, AES.MODE_GCM, init_vector)
        # decrypt password
        return cipher.decrypt(enc_password)[:-16].decode()
    except:
        try:
            return str(win32crypt.CryptUnprotectData(password, None, None, None, 0)[1])
        except:
            return "No Passwords(logged in with Social Account)"

def main():

    # local passwords path
    password_db_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local",
                            "Google", "Chrome", "User Data", "Default", "Login Data")

    #copy the login data file to current directory as "my_chrome_data.db
    shutil.copyfile(password_db_path,"my_chrome_data.db")

    # connect to the database
    db = sqlite3.connect("my_chrome_data.db")
    cursor = db.cursor()

    # run the query
    cursor.execute("SELECT origin_url, username_value, password_value, date_created FROM logins")

    #get the encryption key
    encp_key = encryption_key()
    print("\n|","-"*50, "|\n")
    # iterate over all rows
    for row in cursor.fetchall():
        site_url = row[0]
        username = row[1]
        password = decrypt_password(row[2], encp_key)
        date_created = row[3]

        if username or password:
            print("Site Login URL:", site_url)
            print("Username/Email:", username)
            print(f"Password:",password)
        else:
            continue
        if date_created:
            print("Date date_created:", str(my_chrome_datetime(date_created)))
        print("\n|","-"*50, "|\n")

    cursor.close()
    db.close()

    #remove the copied database after reading passwords
    os.remove("my_chrome_data.db")

if __name__ == "__main__":
    main()

Output

We cannot show the output because of obvious security concerns, and we also recommend you not to share your passwords and credential script output with others.

How to Delete all the stored Chrome Passwords?

Now that you know how to access the Chrome “Login Data” file that stores all the login details, including passwords, you can also perform the SQL delete query on the database with Python SQLite and delete all the stored passwords. The below Python command will delete all the stored passwords, so please execute the code with caution.

#import standared libraies
import sqlite3
import os

my_chrome_db_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local",
"Google", "Chrome", "User Data", "Default", "Login Data")

#connect to database
db = sqlite3.connect(my_chrome_db_path)
cursor = db.cursor()

# query for data
cursor.execute("SELECT origin_url, username_value, password_value FROM logins")

total_passwords = len(cursor.fetchall())
print("Total Passwords to delete:", total_passwords)

#execute delete query
cursor.execute("DELETE FROM logins")
cursor.connection.commit()
print("All passwords have been deleted")

Conclusion

In this Python tutorial, you learned how to extract all stored Chrome password with Python. You also learned how to delete them. The above program for deleting the passwords will delete not only the passwords but also other data within the login table. Thus, we recommend you execute the delete command with caution.

People are also reading:

Author: Vinay

I am a Full Stack Developer with a Bachelor's Degree in Computer Science, who also loves to write technical articles that can help fellow developers.

Leave a Reply

Your email address will not be published. Required fields are marked *