最近有个需求要读取谷歌浏览器的cookie,在网上找了好久都没找到C#版的,最后参考这篇文章(http://www.meilongkui.com/archives/1904,感兴趣的去看下,很硬核)写了个C#的。
首先引入两个nuget包,一个sqlite用于读取cookie,一个bouncycastle用于解密
using (SqliteConnection connection = new SqliteConnection()) { var userprofilePath = Environment.GetEnvironmentVariable("USERPROFILE"); connection.ConnectionString = $@"DataSource={userprofilePath}AppDataLocalGoogleChromeUser DataDefaultCookies"; 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用户名AppDataLocalGoogleChromeUser DataLocal 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); }