DPAPI fails with CryptographicException when trying to decrypt Chrome cookies

前端 未结 2 1725
盖世英雄少女心
盖世英雄少女心 2020-12-10 00:27

i am trying to get session from my Chrome browser. i can see 2 cookie files in Developer Tools. but this is inconvenient for the user to get cookie values from browser, i wo

2条回答
  •  盖世英雄少女心
    2020-12-10 00:38

    For people who are looking for the code, I'm expanding on Cerberus answer. Starting Chrome 80 version, cookies are encrypted using the AES256-GCM algorithm, and the AES encryption key is encrypted with the DPAPI encryption system, and the encrypted key is stored inside the ‘Local State’ file.

    byte[] encryptedData=
    string encKey = File.ReadAllText(localAppDataPath + @"\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);
    _cookie = _decryptWithKey(encryptedData, decodedKey, 3);
    

    Key size is 256 bits. Encypted message format is, pay load('v12')+nonce (12 bytes)+cipherText

    private string _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))
        {
            var nonSecretPayload = cipherReader.ReadBytes(nonSecretPayloadLength);
            var nonce = cipherReader.ReadBytes(NONCE_BIT_SIZE / 8);
            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 Encoding.Default.GetString(plainText);
        }
    }
    

    Needed packages

    1) Newtonsoft JSON .net

    2) Bouncy Castle Crypto package

提交回复
热议问题