'Error decrypting my Google Chrome passwords: 'utf-8' codec can't decode byte
it happens that suddenly one day the autocomplete of Google Chrome stopped working. Look for my passwords in Settings---> Autocomplete---> Passwords and nothing, they weren't there! I did not delete anything, not even cookies... well. Researching on the internet I have used the Chromepassview and it only showed me the usernames and not the passwords. I analyzed the "Login Data" file with DB Browser SQLite and I see the password value in BLOB format. I have managed to convert the passwords to cipher text using the code in this link: https://ohyicong.medium.com/how-to-hack-chrome-password-with-python-1bedc167be3d but not knowing how to continue. I have now copied and pasted (from this link: https://github.com/ohyicong/decrypt-chrome-passwords/blob/main/decrypt_chrome_password.py ) the following python code:
import os
import re
import sys
import json
import base64
import sqlite3
import win32crypt
from Cryptodome.Cipher import AES
import shutil
import csv
#GLOBAL CONSTANT
CHROME_PATH_LOCAL_STATE = os.path.normpath(r"%s\AppData\Local\Google\Local State"%(os.environ['USERPROFILE']))
CHROME_PATH = os.path.normpath(r"%s\AppData\Local\Google\Chrome\User Data"%(os.environ['USERPROFILE']))
def get_secret_key():
try:
#(1) Get secretkey from chrome local state
with open( CHROME_PATH_LOCAL_STATE, "r", encoding='utf-8') as f:
local_state = f.read()
local_state = json.loads(local_state)
secret_key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
#Remove suffix DPAPI
secret_key = secret_key[5:]
secret_key = win32crypt.CryptUnprotectData(secret_key, None, None, None, 0)[1]
return secret_key
except Exception as e:
print("%s"%str(e))
print("[ERR] Chrome secretkey cannot be found")
return None
def decrypt_payload(cipher, payload):
return cipher.decrypt(payload)
def generate_cipher(aes_key, iv):
return AES.new(aes_key, AES.MODE_GCM, iv)
def decrypt_password(ciphertext, secret_key):
try:
#(3-a) Initialisation vector for AES decryption
initialisation_vector = ciphertext[3:15]
#(3-b) Get encrypted password by removing suffix bytes (last 16 bits)
#Encrypted password is 192 bits
encrypted_password = ciphertext[15:-16]
#(4) Build the cipher to decrypt the ciphertext
cipher = generate_cipher(secret_key, initialisation_vector)
decrypted_pass = decrypt_payload(cipher, encrypted_password)
decrypted_pass = decrypted_pass.decode()
return decrypted_pass
except Exception as e:
print("%s"%str(e))
print("[ERR] Unable to decrypt, Chrome version <80 not supported. Please check.")
return ""
def get_db_connection(chrome_path_login_db):
try:
print(chrome_path_login_db)
shutil.copy2(chrome_path_login_db, "Loginvault.db")
return sqlite3.connect("Loginvault.db")
except Exception as e:
print("%s"%str(e))
print("[ERR] Chrome database cannot be found")
return None
if __name__ == '__main__':
try:
#Create Dataframe to store passwords
with open('decrypted_password.csv', mode='w', newline='', encoding='utf-8') as decrypt_password_file:
csv_writer = csv.writer(decrypt_password_file, delimiter=',')
csv_writer.writerow(["index","url","username","password"])
#(1) Get secret key
secret_key = get_secret_key()
#Search user profile or default folder (this is where the encrypted login password is stored)
folders = [element for element in os.listdir(CHROME_PATH) if re.search("^Profile*|^Default$",element)!=None]
for folder in folders:
#(2) Get ciphertext from sqlite database
chrome_path_login_db = os.path.normpath(r"%s\%s\Login Data"%(CHROME_PATH,folder))
conn = get_db_connection(chrome_path_login_db)
if(secret_key and conn):
cursor = conn.cursor()
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]
if(url!="" and username!="" and ciphertext!=""):
#(3) Filter the initialisation vector & encrypted password from ciphertext
#(4) Use AES algorithm to decrypt the password
decrypted_password = decrypt_password(ciphertext, secret_key)
print("Sequence: %d"%(index))
print("URL: %s\nUser Name: %s\nPassword: %s\n"%(url,username,decrypted_password))
print("*"*50)
#(5) Save into CSV
csv_writer.writerow([index,url,username,decrypted_password])
#Close database connection
cursor.close()
conn.close()
#Delete temp login db
os.remove("Loginvault.db")
except Exception as e:
print("[ERR] "%str(e))
The problem is that the code only decrypts those passwords that I re-inserted after all will be deleted. For the rest it shows me the url, username, but the password is empty, like in the following message (2 examples here):
'utf-8' codec can't decode byte 0xef in position 2: invalid start byte
[ERR] Unable to decrypt, Chrome version <80 not supported. Please check.
Sequence: 32
URL: https://www.crunchyroll.com/
User Name: [email protected]
Password:
or:
'utf-8' codec can't decode byte 0xde in position 0: invalid continuation byte
[ERR] Unable to decrypt, Chrome version <80 not supported. Please check.
Sequence: 63
URL: https://www.researchgate.net/signup.SignUpAccountBasics.html
User Name: [email protected]
Password:
I use python at a basic level and I understand a little how AES encryption works, what could I do to solve it?
Solution 1:[1]
update your chrome version because this code won't work if the chrome version was less than 80
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Majd khalifeh |
