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 would like to do it in code. so i use this code to get Chrome default profile cookie sqlite DB:
string local = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
string path = @"GoogleChromeUser DataDefaultCookies";
path = Path.Combine(local, path);
next i create SQLite connection and request
var cmd = new SQLiteCommand("SELECT encrypted_value, name FROM cookies WHERE host_key = 'my_host_ip'", con);
then i read the results
byte[] encryptedCookie = (byte[])r.GetValue(r.GetOrdinal("encrypted_value"));
and try to decrypt it:
var decodedData = ProtectedData.Unprotect(encryptedCookie, null, DataProtectionScope.CurrentUser);
var plainText = Encoding.ASCII.GetString(decodedData);
and here i got exception
System.Security.Cryptography.CryptographicException
i know that i MUST decrypt cookie contents under the same user account under which the browser was launched (on the same machine), and parameter DataProtectionScope.CurrentUser
is used for that
i see 63 bytes in debugger (in encryptedCookie
array), i also see this bytes in SQLite DB BLOB field.
but Unprotect
method throws System.Security.Cryptography.CryptographicException: Invalid data
error.
my code works fine at 5 different PC's in my office (win10, win7), but didnt work on my developer PC (win10, vs2019).
i think that the problem is in my Windows Settings or somewhere else, not in my code. so what i am doing wrong?
interesting note - i found PowerShell script that does the same thing (through Add-Type -AssemblyName System.Security
) - get cookie and decrypt it. this script also works fine at 5 office PC's, but didnt work at my PC.
my Windows installation is new, i have no AV software. we connected to the same Corporate domain and we have the same security settings.
UPD 1
a little expreriment:
- get cookie value from Chrome browser (32 chars, JSESSIONID)
- create a simple app that protects this value with
CurrentUser
protection scope. now i have an array of 178 bytes (result #1)
- view Chrome's cookies database with a) https://sqliteonline.com/ and b) DataBase.Net desktop app. this two methods give me the same result: only 63 bytes of encrypted cookie data (result #2). i can also get the same result with my c# application using
System.Data.SQLite
so, the results are not equal in length or content
result #1 != result #2
looks like Chrome's cookie value protected by different scope (maybe admin account?), but i see my user account name in Task Manager in Chrome's process
P.S. i use .net 4.7.2
UPD 2
i found this method in Chromium sources
bool OSCrypt::DecryptString(const std::string& ciphertext,
std::string* plaintext) {
if (!base::StartsWith(ciphertext, kEncryptionVersionPrefix,
base::CompareCase::SENSITIVE))
return DecryptStringWithDPAPI(ciphertext, plaintext);
crypto::Aead aead(crypto::Aead::AES_256_GCM);
auto key = GetEncryptionKeyInternal();
aead.Init(&key);
// Obtain the nonce.
std::string nonce =
ciphertext.substr(sizeof(kEncryptionVersionPrefix) - 1, kNonceLength);
// Strip off the versioning prefix before decrypting.
std::string raw_ciphertext =
ciphertext.substr(kNonceLength + (sizeof(kEncryptionVersionPrefix) - 1));
return aead.Open(raw_ciphertext, nonce, std::string(), plaintext);
}
so DPAPI is only used when BLOB NOT starts with v10
chars. but my cookie BLOBs starts with v10
chars, and, according to the code, another crypto-algorithm is used, but i dont understand WHY.
See Question&Answers more detail:
os