Do you think it is safe to store your password in Chrome? The short answer is “no”. Any perpetrator that has access to your laptop is able to decrypt all your password within seconds.
The convenience comes with a price
It is undeniable that saving your password in Chrome is convenient. It helps you to log in to your website automatically while ensuring that your password is encrypted. The only way for the perpetrators to access your encrypted website password is to have your laptop username and password.
The false sense of security
To be honest, the windows login prompt is a weak security feature. Have you ever wondered how Chrome auto-fill the password fields without any prompt? This is because Chrome has saved your passwords somewhere else in the application.
Of note, they did not save in a secured location.
Steps to decrypt Chrome passwords
There are four main steps to decrypt Chrome passwords
- Find the encryption key
- Find the encrypted passwords
- Understand AES cryptography
- Decrypt the saved passwords
Step 1: Find the encryption key
(1) The encryption key is stored in a JSON file which can be found in the following location on your Windows PC.
C:\Users\<PC Name>\AppData\Local\Google\Chrome\User Data\Local State
Upon opening the file, search for the word “encrypted_key” as shown in the image below:
Voila! You have found the key to decrypt the saved password.
Step 2: Find the encrypted passwords
The encrypted password is stored in an SQLite database which can be found in the following location of your Windows PC
C:\Users\<PC Name>\AppData\Local\Google\Chrome\User Data\Default\Login Data
To extract the encrypted password you need an SQLite3 database connection. Run the following code to extract it.
#Chrome username & password file path
chrome_path_login_db = "C:\Users\<PC Name>\AppData\Local\Google\Chrome\User Data\Default\Login Data"
shutil.copy2(chrome_path_login_db, "Loginvault.db") #Connect to sqlite database
sqlite3.connect("Loginvault.db")
cursor = conn.cursor()#Select statement to retrieve info
cursor.execute("SELECT action_url, username_value, password_value FROM logins")
for index,login in enumerate(cursor.fetchall()):
url = login[0]
username = login[1]
ciphertext= login[2]
print("Url:",url)
print("Username",username)
print("Cipher Text",ciphertext)
After the code execution, you will be able to retrieve three critical pieces of information:
- Url
- Username
- Ciphertext
Within the ciphertext, it contains two important sub information required for AES decryption:
- Initialization vector
- Encrypted passwords
The initialization vector is stored between characters 4 to 20, while the encrypted password is stored between characters 21 to N-16 (i.e. total characters minus 16).
Step 3: Understand AES cryptography
In order to decrypt the password, we need to first understand AES cryptography which is a symmetric key algorithm used by Chrome to encrypt and decrypt the passwords.
AES uses the encryption key and performs complex mathematical row operations (e.g. addition, subtraction, mixing, and shifting) to encrypt the password.
To improve its security, an initialization vector (a random string of data) can be added, making it more difficult for the perpetrator to crack the password as he has to find both the encryption key and initialization vector to perform AES cryptography.
The following is the block diagram showing the mechanism of AES cryptography:
After AES, the encrypted key is stored in the Local State File, while the encrypted password is concatenated with the initialization vector and stored into the SQLite3 database as ciphertext.
Step 4: Decrypt the saved passwords
Knowing that AES is symmetric-key cryptography where it uses the same key for both encryption and decryption. We can use the encrypted key and initialization vector that we discovered to decrypt the passwords with AES cryptography.
#Step 1: Extracting initilisation vector from ciphertext
initialisation_vector = ciphertext[3:15]#Step 2: Extracting encrypted password from ciphertext
encrypted_password = ciphertext[15:-16]#Step 3:Build the AES algorithm to decrypt the password
cipher = AES.new(secret_key, AES.MODE_GCM, initialisation_vector)
decrypted_pass = cipher.decrypt(encrypted_password)
decrypted_pass = decrypted_pass.decode()#Step 4: Decrypted Password
print(decrypted_pass)
Results
After the code execution, you will be able to retrieve the URL, username, and password from Chrome.
Learning Materials
For a full code please visit: https://github.com/ohyicong/decrypt-chrome-passwords
To learn how to decrypt firefox password visit: https://ohyicong.medium.com/how-to-hack-firefox-passwords-with-python-a394abf18016
Disclaimer
I am sharing this knowledge to raise awareness of this vulnerability and demonstrate how easy this can be exploited. You should not use this tool on unauthorised devices. Cheers!