Знаю что в файле "Local State" хранится ключ для работ с AES_256_GCM, а в базе данных "Logins Data" хранятся пароли закодированные либо AES_256_GCM либо DPAPI. Но при попытке их раскодировать ничего не получается. Помогите пожалуйста разобраться почему ничего не работает. Есть несколько вариантов кода.
На python:
import win32crypt, base64
from Cryptodome.Cipher import AES
key = base64.b64decode(open("./key.txt", "rb").read())[5:]
key = win32crypt.CryptUnprotectData(key, None, None, None, 0)[1]
print("Key:", key, len(key))
encoded = open("encoded_password.txt", "rb").read()[3:]
iv = encoded[:12]
tag = encoded[-16:]
encoded_pass = encoded[12:]
cipher = AES.new(key, AES.MODE_GCM, nonce=iv)
plaintext = cipher.decrypt(encoded_pass)
result = open("./result.txt", "wb")
result.write(plaintext)
result.close()
И 2 шт. на C#:
byte[] encryptedData = File.ReadAllBytes(@"C:\Users\Denis\Desktop\chrome\encoded_password.txt");
string encKey = File.ReadAllText(@"C:\Users\Denis\AppData\Local\Google\Chrome\User Data\Local State");
encKey = JObject.Parse(encKey)["os_crypt"]["encrypted_key"].ToString();
var decodedKey = System.Security.Cryptography.ProtectedData.Unprotect(Convert.FromBase64String(encKey).Skip(5).ToArray(), null, System.Security.Cryptography.DataProtectionScope.LocalMachine);
for(int i = 0;i < 1024; i++)
{
var _cookie = _decryptWithKey(encryptedData, decodedKey, i);
if(_cookie != null)
{
foreach (var j in _cookie) Console.Write(((int)j));
}
}
byte[] _decryptWithKey(byte[] message, byte[] key, int nonSecretPayloadLength)
{
const int KEY_BIT_SIZE = 256;
const int MAC_BIT_SIZE = 128;
const int NONCE_BIT_SIZE = 96;
if (key == null || key.Length != KEY_BIT_SIZE / 8)
throw new ArgumentException(String.Format("Key needs to be {0} bit!", KEY_BIT_SIZE), "key");
if (message == null || message.Length == 0)
throw new ArgumentException("Message required!", "message");
using (var cipherStream = new MemoryStream(message))
using (var cipherReader = new BinaryReader(cipherStream))
{
cipherReader.ReadBytes(3);
var nonce = cipherReader.ReadBytes(NONCE_BIT_SIZE / 8);
var nonSecretPayload = cipherReader.ReadBytes(nonSecretPayloadLength);
var cipher = new GcmBlockCipher(new AesEngine());
var parameters = new AeadParameters(new KeyParameter(key), MAC_BIT_SIZE, nonce);
cipher.Init(false, parameters);
var cipherText = cipherReader.ReadBytes(message.Length);
var plainText = new byte[cipher.GetOutputSize(cipherText.Length)];
try
{
var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0);
cipher.DoFinal(plainText, len);
}
catch (InvalidCipherTextException)
{
return null;
}
return plainText;
}
}
string key = "Здесь ключ из Local State";
byte[] key_bytes = Convert.FromBase64String(key).Skip(5).ToArray();
key_bytes = ProtectedData.Unprotect(key_bytes, null, DataProtectionScope.CurrentUser);
SQLiteConnection Connection = new SQLiteConnection(@"Data Source=D:\Projects\GoogleLoginDataDecode\Login Data.db");
SQLiteCommand Command = new SQLiteCommand
{
Connection = Connection,
CommandText = "SELECT * FROM logins"
};
DataSet data = new DataSet();
SQLiteDataAdapter adapter = new SQLiteDataAdapter(Command);
adapter.Fill(data);
foreach (DataTable dt in data.Tables)
{
for(int i = 0;i < dt.Rows.Count; i++)
{
var cells = dt.Rows[i].ItemArray;
Console.Write(cells[0].ToString());
byte[] password_bytes = (byte[])cells[5];
password_bytes = password_bytes.Skip(3).ToArray();
byte[] nonce = password_bytes.Take(12).ToArray();
password_bytes = password_bytes.Skip(12).ToArray();
byte[] tag = password_bytes.Reverse().Take(16).Reverse().ToArray();
byte[] encoded = password_bytes.Reverse().Skip(16).Reverse().ToArray();
byte[] password = new byte[encoded.Length];
AesGcm aead = new AesGcm(key_bytes);
aead.Decrypt(nonce, encoded, tag, password);
Console.Write(Encoding.UTF8.GetString(password));
Console.WriteLine();
}
}