浏览器中保存的账号密码,如何不使用电脑密码就解开。

第一步

需要备份两个文件

1、账号密码信息被加密之后的文件

C:\Users\你的用户名\AppData\Local\Google\Chrome\User Data\Default\Login Data

2、解开加密文件的密钥

C:\Users\你的用户名\AppData\Local\Google\Chrome\User Data\Local State

第二步

下载我提供的代码,并把代码开头处的两个变量
login_data_path 、 local_state_path
修改到第一步中你备份的路径

夸克网盘 
链接:https://pan.quark.cn/s/bfce67ff4e69

多说两句

Chrome 遵循的是Chromium的开源架构,Chromium的开源代码中,明确写出了自己的解密过程,如下:

https://source.chromium.org/chromium/chromium/src/+/main:components/os_crypt/sync/os_crypt_win.cc;l=1?q=os_crypt_win&sq=&ss=chromium

在 os_crypt_win.cc 代码中的 bool OSCryptImpl::DecryptString 方法

所以我做的并不是破解,而仅仅是翻译

代码源码

import os
import sqlite3
import json
import base64
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
import ctypes
from ctypes import wintypes

login_data_path = "C:\Mine\Project\chromed\Login Data"
local_state_path = "C:\Mine\Project\chromed\Local State"

class AES_GCM:
    @staticmethod
    def encrypt(cipher, plaintext, nonce):
        cipher.mode = modes.GCM(nonce)
        encryptor = cipher.encryptor()
        ciphertext = encryptor.update(plaintext)
        return cipher, ciphertext, nonce

    @staticmethod
    def decrypt(cipher, ciphertext, nonce):
        cipher.mode = modes.GCM(nonce)
        decryptor = cipher.decryptor()
        return decryptor.update(ciphertext)

    @staticmethod
    def get_cipher(key):
        cipher = Cipher(algorithms.AES(key), None, backend=default_backend())
        return cipher

def dpapi_decrypt(encrypted):
    class DATA_BLOB(ctypes.Structure):
        _fields_ = [('cbData', wintypes.DWORD),
                    ('pbData', ctypes.POINTER(ctypes.c_char))]
    try:
        p = ctypes.create_string_buffer(encrypted, len(encrypted))
        blobin = DATA_BLOB(ctypes.sizeof(p), p)
        blobout = DATA_BLOB()
        retval = ctypes.windll.crypt32.CryptUnprotectData(
            ctypes.byref(blobin), None, None, None, None, 0, ctypes.byref(blobout))
        if not retval:
            raise ctypes.WinError()
        result = ctypes.string_at(blobout.pbData, blobout.cbData)
        return result
    except Exception as e:
        print(f"Error in dpapi_decrypt: {e}")
        return None

def get_key_from_local_state():
    with open(local_state_path, encoding='utf-8', mode="r") as f:
        jsn = json.loads(str(f.readline()))
    return jsn["os_crypt"]["encrypted_key"]

def aes_decrypt(encrypted_txt):
    encoded_key = get_key_from_local_state()
    encrypted_key = base64.b64decode(encoded_key.encode())
    encrypted_key = encrypted_key[5:]
    key = dpapi_decrypt(encrypted_key)
    nonce = encrypted_txt[3:15]
    cipher = AES_GCM.get_cipher(key)
    return AES_GCM.decrypt(cipher, encrypted_txt[15:], nonce)

def chrome_decrypt(encrypted_txt):
    if encrypted_txt[:4] == b'x01x00x00x00':
        decrypted_txt = dpapi_decrypt(encrypted_txt)
        return decrypted_txt.decode()
    elif encrypted_txt[:3] == b'v10':
        decrypted_txt = aes_decrypt(encrypted_txt)
        return decrypted_txt[:-16].decode()

def query_logindata(url):
    if url:
        sql = f"select origin_url, username_value, password_value from logins where origin_url = '{url}'"
    else:
        sql = "select origin_url, username_value, password_value from logins"
    with sqlite3.connect(login_data_path) as conn:
        result = conn.execute(sql).fetchall()
    return result

if __name__ == '__main__':
    print("Decrypt Login Data:")
    logindata = query_logindata("") # 可以传入参数筛选指定url
    for data in logindata:
        login = data[0], data[1], chrome_decrypt(data[2])
        print(login)