Home > Back-end >  How to convert SQLite Blob field to string with Python
How to convert SQLite Blob field to string with Python

Time:02-10

I want to open the Chrome (Login Data) file and use its password field. But this field is stored in byte/blob mode and can not be converted to text.

I also tried codecs and pickle and bytes.encode and str.decode but it didn't work. Please look at the code below and help :

import sqlite3

connection_obj = sqlite3.connect('C:/Users/{username}/AppData/Local/Google/Chrome/User 
Data/Default/Login Data')

cursor_obj = connection_obj.cursor()

statement = '''SELECT action_url, username_value, password_value  FROM logins'''

cursor_obj.execute(statement)

output = cursor_obj.fetchmany(5)

for url,usr,psw in output:
     # convert psw blob -> ascii text
     # ....
     # ....
     # for example psw filed:
     # b'v10\x7f\xa3\x1a\xd1\x83g\x8c\xc4\x14]\xb6n\xf85\xba\xca\xf5r\x17\xb6D\xed\xf5\x11rM\xbe\xbf\xb1\xc2y\xc5Vr\xc3\xb3NB\xc7J\x14\x95'
     # 
     # convert to below text : 
     # zarfilm-136342

   print(url, usr, psw,sep='------') 
   print('*'*10)

connection_obj.commit()
connection_obj.close()

CodePudding user response:

That data is encrypted in AES, and further the key is encrypted with CryptProtectData to lock the encryption key to user data. You can decrypt the data with something like this:

import base64, json, os, sqlite3, win32crypt
from Crypto.Cipher import AES

def chrome_key():
    local_state_fn = os.path.join(os.environ["USERPROFILE"],"AppData","Local","Google","Chrome","User Data","Local State")
    with open(local_state_fn, "r") as f:
        local_state = json.load(f)
    key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
    key = key[5:]
    return win32crypt.CryptUnprotectData(key, None, None, None, 0)[1]

def decrypt_password(password, key):
    iv, password = password[3:15], password[15:]
    aes = AES.new(key, AES.MODE_GCM, iv)
    return aes.decrypt(password)[:-16].decode("utf-8")

def main():
    key = chrome_key()
    db_fn = os.path.join(os.environ["USERPROFILE"],"AppData","Local","Google","Chrome","User Data","default","Login Data")
    db = sqlite3.connect(db_fn)
    for origin_url, username, password_crypt in db.execute("SELECT origin_url, username_value, password_value FROM logins;"):
        password = decrypt_password(password_crypt, key)
        print(f"{origin_url}, {username}, {password}")
    db.close()

if __name__ == "__main__":
    main()

CodePudding user response:

Are you surprised to learn that this field is encrypted? Google would be in for a world of trouble if it wasn't. Even Chrome doesn't know how to decrypt this. It's done with the Windows cryptography APIs, and involved your Windows login password. You can't get them.

  • Related