在 c# .Net Framework 中解密 Google Cookies?
Decrypt Google Cookies in c# .Net Framework?
我已经创建了这个,它能够在给定特定域名时从 Google Chrome 获取 cookie。但是,这些值已解密。我知道一定有一种方法可以修改我的代码来解密这些值。
using Microsoft.Data.Sqlite;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Test
{
public class Test
{
public List<Data> GetCookies(string hostname)
{
List<Data> data = new List<Data>();
if (ChromeCookiesExists())
{
try
{
using (var conn = new SqliteConnection($"Data Source={ChromeCookiePath}"))
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = $"SELECT name,encrypted_value,host_key FROM cookies WHERE host_key = '{hostname}'";
conn.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
if (!data.Any(a => a.Name == reader.GetString(0)))
{
data.Add(new Data()
{
Name = reader.GetString(0),
Value = reader.GetString(1) //HERE is my problem because this returns encrypted value not decrypted
});
}
}
}
conn.Close();
}
}
catch { }
}
return data;
}
private string ChromeCookiePath = @"C:\Users\" + Environment.UserName + @"\AppData\Local\Google\Chrome\User Data\Default\Cookies";
private bool ChromeCookiesExists()
{
if (File.Exists(ChromeCookiePath))
return true;
return false;
}
public class Data
{
public string Name { get; set; }
public string Value { get; set; }
}
}
}
此代码输出一个名为 Data 的结构,其中包含 cookie 的名称和值(只是未解密的 atm)。
多亏了 Topaco 的评论和 UnCavoHDMI,我才能够把它放在一起。
class ChromeManager
{
public List<Cookie> GetCookies(string hostname)
{
string ChromeCookiePath = @"C:\Users\" + Environment.UserName + @"\AppData\Local\Google\Chrome\User Data\Default\Cookies";
List<Cookie> data = new List<Cookie>();
if (File.Exists(ChromeCookiePath))
{
try
{
using (var conn = new SqliteConnection($"Data Source={ChromeCookiePath}"))
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = $"SELECT name,encrypted_value,host_key FROM cookies WHERE host_key = '{hostname}'";
byte[] key = AesGcm256.GetKey();
conn.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
if (!data.Any(a => a.Name == reader.GetString(0)))
{
byte[] encryptedData = GetBytes(reader, 1);
byte[] nonce, ciphertextTag;
AesGcm256.prepare(encryptedData, out nonce, out ciphertextTag);
string value = AesGcm256.decrypt(ciphertextTag, key, nonce);
data.Add(new Cookie()
{
Name = reader.GetString(0),
Value = value
});
}
}
}
conn.Close();
}
}
catch { }
}
return data;
}
private byte[] GetBytes(SqliteDataReader reader, int columnIndex)
{
const int CHUNK_SIZE = 2 * 1024;
byte[] buffer = new byte[CHUNK_SIZE];
long bytesRead;
long fieldOffset = 0;
using (MemoryStream stream = new MemoryStream())
{
while ((bytesRead = reader.GetBytes(columnIndex, fieldOffset, buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, (int)bytesRead);
fieldOffset += bytesRead;
}
return stream.ToArray();
}
}
public class Cookie
{
public string Name { get; set; }
public string Value { get; set; }
}
class AesGcm256
{
public static byte[] GetKey()
{
string sR = string.Empty;
var appdata = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string path = @"C:\Users\" + Environment.UserName + @"\AppData\Local\Google\Chrome\User Data\Local State";
string v = File.ReadAllText(path);
dynamic json = JsonConvert.DeserializeObject(v);
string key = json.os_crypt.encrypted_key;
byte[] src = Convert.FromBase64String(key);
byte[] encryptedKey = src.Skip(5).ToArray();
byte[] decryptedKey = ProtectedData.Unprotect(encryptedKey, null, DataProtectionScope.CurrentUser);
return decryptedKey;
}
public static string decrypt(byte[] encryptedBytes, byte[] key, byte[] iv)
{
string sR = String.Empty;
try
{
GcmBlockCipher cipher = new GcmBlockCipher(new AesEngine());
AeadParameters parameters = new AeadParameters(new KeyParameter(key), 128, iv, null);
cipher.Init(false, parameters);
byte[] plainBytes = new byte[cipher.GetOutputSize(encryptedBytes.Length)];
Int32 retLen = cipher.ProcessBytes(encryptedBytes, 0, encryptedBytes.Length, plainBytes, 0);
cipher.DoFinal(plainBytes, retLen);
sR = Encoding.UTF8.GetString(plainBytes).TrimEnd("\r\n[=10=]".ToCharArray());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
return sR;
}
public static void prepare(byte[] encryptedData, out byte[] nonce, out byte[] ciphertextTag)
{
nonce = new byte[12];
ciphertextTag = new byte[encryptedData.Length - 3 - nonce.Length];
System.Array.Copy(encryptedData, 3, nonce, 0, nonce.Length);
System.Array.Copy(encryptedData, 3 + nonce.Length, ciphertextTag, 0, ciphertextTag.Length);
}
}
}
我已经创建了这个,它能够在给定特定域名时从 Google Chrome 获取 cookie。但是,这些值已解密。我知道一定有一种方法可以修改我的代码来解密这些值。
using Microsoft.Data.Sqlite;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Test
{
public class Test
{
public List<Data> GetCookies(string hostname)
{
List<Data> data = new List<Data>();
if (ChromeCookiesExists())
{
try
{
using (var conn = new SqliteConnection($"Data Source={ChromeCookiePath}"))
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = $"SELECT name,encrypted_value,host_key FROM cookies WHERE host_key = '{hostname}'";
conn.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
if (!data.Any(a => a.Name == reader.GetString(0)))
{
data.Add(new Data()
{
Name = reader.GetString(0),
Value = reader.GetString(1) //HERE is my problem because this returns encrypted value not decrypted
});
}
}
}
conn.Close();
}
}
catch { }
}
return data;
}
private string ChromeCookiePath = @"C:\Users\" + Environment.UserName + @"\AppData\Local\Google\Chrome\User Data\Default\Cookies";
private bool ChromeCookiesExists()
{
if (File.Exists(ChromeCookiePath))
return true;
return false;
}
public class Data
{
public string Name { get; set; }
public string Value { get; set; }
}
}
}
此代码输出一个名为 Data 的结构,其中包含 cookie 的名称和值(只是未解密的 atm)。
多亏了 Topaco 的评论和 UnCavoHDMI,我才能够把它放在一起。
class ChromeManager
{
public List<Cookie> GetCookies(string hostname)
{
string ChromeCookiePath = @"C:\Users\" + Environment.UserName + @"\AppData\Local\Google\Chrome\User Data\Default\Cookies";
List<Cookie> data = new List<Cookie>();
if (File.Exists(ChromeCookiePath))
{
try
{
using (var conn = new SqliteConnection($"Data Source={ChromeCookiePath}"))
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = $"SELECT name,encrypted_value,host_key FROM cookies WHERE host_key = '{hostname}'";
byte[] key = AesGcm256.GetKey();
conn.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
if (!data.Any(a => a.Name == reader.GetString(0)))
{
byte[] encryptedData = GetBytes(reader, 1);
byte[] nonce, ciphertextTag;
AesGcm256.prepare(encryptedData, out nonce, out ciphertextTag);
string value = AesGcm256.decrypt(ciphertextTag, key, nonce);
data.Add(new Cookie()
{
Name = reader.GetString(0),
Value = value
});
}
}
}
conn.Close();
}
}
catch { }
}
return data;
}
private byte[] GetBytes(SqliteDataReader reader, int columnIndex)
{
const int CHUNK_SIZE = 2 * 1024;
byte[] buffer = new byte[CHUNK_SIZE];
long bytesRead;
long fieldOffset = 0;
using (MemoryStream stream = new MemoryStream())
{
while ((bytesRead = reader.GetBytes(columnIndex, fieldOffset, buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, (int)bytesRead);
fieldOffset += bytesRead;
}
return stream.ToArray();
}
}
public class Cookie
{
public string Name { get; set; }
public string Value { get; set; }
}
class AesGcm256
{
public static byte[] GetKey()
{
string sR = string.Empty;
var appdata = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string path = @"C:\Users\" + Environment.UserName + @"\AppData\Local\Google\Chrome\User Data\Local State";
string v = File.ReadAllText(path);
dynamic json = JsonConvert.DeserializeObject(v);
string key = json.os_crypt.encrypted_key;
byte[] src = Convert.FromBase64String(key);
byte[] encryptedKey = src.Skip(5).ToArray();
byte[] decryptedKey = ProtectedData.Unprotect(encryptedKey, null, DataProtectionScope.CurrentUser);
return decryptedKey;
}
public static string decrypt(byte[] encryptedBytes, byte[] key, byte[] iv)
{
string sR = String.Empty;
try
{
GcmBlockCipher cipher = new GcmBlockCipher(new AesEngine());
AeadParameters parameters = new AeadParameters(new KeyParameter(key), 128, iv, null);
cipher.Init(false, parameters);
byte[] plainBytes = new byte[cipher.GetOutputSize(encryptedBytes.Length)];
Int32 retLen = cipher.ProcessBytes(encryptedBytes, 0, encryptedBytes.Length, plainBytes, 0);
cipher.DoFinal(plainBytes, retLen);
sR = Encoding.UTF8.GetString(plainBytes).TrimEnd("\r\n[=10=]".ToCharArray());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
return sR;
}
public static void prepare(byte[] encryptedData, out byte[] nonce, out byte[] ciphertextTag)
{
nonce = new byte[12];
ciphertextTag = new byte[encryptedData.Length - 3 - nonce.Length];
System.Array.Copy(encryptedData, 3, nonce, 0, nonce.Length);
System.Array.Copy(encryptedData, 3 + nonce.Length, ciphertextTag, 0, ciphertextTag.Length);
}
}
}