C# 获取并解密谷歌浏览器Cookie

作者: zengde 分类: 笔记 发布时间: 2022-01-04 07:45

最近有个需求要读取谷歌浏览器的cookie,在网上找了好久都没找到C#版的,最后参考这篇文章(http://www.meilongkui.com/archives/1904,感兴趣的去看下,很硬核)写了个C#的。

首先引入nuget包,一个Microsoft.Data.Sqlite用于读取cookie,而bouncycastle,System.Security.Cryptography.ProtectedData用于解密

using (SqliteConnection connection = new SqliteConnection())
{
    var userprofilePath = Environment.GetEnvironmentVariable("USERPROFILE");
    connection.ConnectionString = $@"DataSource={userprofilePath}\AppData\Local\Google\Chrome\User Data\Default\Cookies";
    connection.Open();
    SqliteCommand command = new SqliteCommand("select host_key,name,encrypted_value from cookies where host_key='.baidu.com'", connection);
    SqliteDataReader dataReader = command.ExecuteReader();
    dataReader.Read();
    byte[] encryptedValue = (byte[])dataReader["encrypted_value"];

    int keyLength = 256 / 8;
    int nonceLength = 96 / 8;
    String kEncryptionVersionPrefix = "v10";
    int GCM_TAG_LENGTH = 16;
   //字符串内容取自C:\Users\用户名\AppData\Local\Google\Chrome\User Data\Local State文件的encrypted_key
    byte[] encryptedKeyBytes = Convert.FromBase64String("RFBBUEkBAAAA0Iyd3wEV0RGMegDAT8KX6wEAAAA3PHk3a5NmQpRxjGtdwCCCAAAAAAIAAAAAABBmAAAAAQAAIAAAALd7GZJyVqp7yQUBIEUvv0cwGN/mdUVrvAqqgbdJyJwoAAAAAA6AAAAAAgAAIAAAAPjIbfKCXRBggBNixV8sG409GYD9QRUHpiRMf/7s7Nm7MAAAABobpenJlhdxFJQw5PI1Fk/X0COpn+HZUxNl+GahUsmydEdXWJg0w5KmZjC7QjKJ/EAAAAA/rz1g3B2SdeXFMesLCZ/5O+xEDYxjeUP1hCw4Fa9rrLeUWpLkmmgL9JRNvSaiMfISpGXcWsr5zvhOLaF2kJ81");

    encryptedKeyBytes = encryptedKeyBytes.Skip("DPAPI".Length).Take(encryptedKeyBytes.Length- "DPAPI".Length).ToArray();

    var keyBytes = System.Security.Cryptography.ProtectedData.Unprotect(encryptedKeyBytes, null, System.Security.Cryptography.DataProtectionScope.CurrentUser);

    var nonce = encryptedValue.Skip(kEncryptionVersionPrefix.Length).Take( nonceLength).ToArray();

    encryptedValue = encryptedValue.Skip(kEncryptionVersionPrefix.Length + nonceLength).Take(encryptedValue.Length- (kEncryptionVersionPrefix.Length + nonceLength)).ToArray();

    var str = AesGcmDecrypt(keyBytes, nonce, encryptedValue);
    Console.WriteLine($"{dataReader["host_key"]}-{dataReader["name"]}-{str}");
    connection.Close();
}


public static string AesGcmDecrypt(byte[] keyBytes, byte[] nonce, byte[] encryptedValue)
{
    
    GcmBlockCipher gcmBlockCipher = new GcmBlockCipher(new AesEngine());
    AeadParameters aeadParameters = new AeadParameters(
        new KeyParameter(keyBytes),
        128,
        nonce);
    gcmBlockCipher.Init(false, aeadParameters);
    byte[] plaintext = new byte[gcmBlockCipher.GetOutputSize(encryptedValue.Length)];
    int length = gcmBlockCipher.ProcessBytes(encryptedValue, 0, encryptedValue.Length, plaintext, 0);
    gcmBlockCipher.DoFinal(plaintext, length);
    return Encoding.UTF8.GetString(plaintext);

}