title: DPAPI fails with CryptographicException when trying to decrypt Chrome cookies
body: <p>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:</p>
  
  <pre><code>string local = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
  string path = @"Google\Chrome\User Data\Default\Cookies";
  
  path = Path.Combine(local, path);
  </code></pre>
  
  <p>next i create SQLite connection and request</p>
  
  <pre><code>var cmd = new SQLiteCommand("SELECT encrypted_value, name FROM cookies WHERE host_key = 'my_host_ip'", con);
  </code></pre>
  
  <p>then i read the results</p>
  
  <pre><code>byte[] encryptedCookie = (byte[])r.GetValue(r.GetOrdinal("encrypted_value"));
  </code></pre>
  
  <p>and try to decrypt it:</p>
  
  <pre><code>var decodedData = ProtectedData.Unprotect(encryptedCookie, null, DataProtectionScope.CurrentUser);
  var plainText = Encoding.ASCII.GetString(decodedData);
  </code></pre>
  
  <p>and here i got exception</p>
  
  <p><code>System.Security.Cryptography.CryptographicException</code></p>
  
  <p>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 <code>DataProtectionScope.CurrentUser</code> is used for that</p>
  
  <p>i see 63 bytes in debugger (in <code>encryptedCookie</code> array), i also see this bytes in SQLite DB BLOB field.
  but <code>Unprotect</code> method throws <code>System.Security.Cryptography.CryptographicException: Invalid data</code> error.</p>
  
  <p>my code works fine at 5 different PC's in my office (win10, win7), but didnt work on my developer PC (win10, vs2019).</p>
  
  <p>i think that the problem is in my Windows Settings or somewhere else, not in my code. so what i am doing wrong?</p>
  
  <p>interesting note - i found PowerShell script that does the same thing (through <code>Add-Type -AssemblyName System.Security</code>) - get cookie and decrypt it. this script also works fine at 5 office PC's, but didnt work at my PC.</p>
  
  <p>my Windows installation is new, i have no AV software. we connected to the same Corporate domain and we have the same security settings.</p>
  
  <p><strong>UPD 1</strong>
  a little expreriment:</p>
  
  <ol>
  <li>get cookie value from Chrome browser (32 chars, JSESSIONID)</li>
  <li>create a simple app that protects this value with <code>CurrentUser</code> protection scope. now i have an array of 178 bytes (result #1)</li>
  <li>view Chrome's cookies database with a) <a href="https://sqliteonline.com/" rel="nofollow noreferrer">https://sqliteonline.com/</a> 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 <code>System.Data.SQLite</code></li>
  </ol>
  
  <p>so, the results are not equal in length or content
  result #1 != result #2</p>
  
  <p>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>
  
  <p>P.S. i use .net 4.7.2</p>
  
  <p><strong>UPD 2</strong>
  i found this method in Chromium sources</p>
  
  <pre><code>bool OSCrypt::DecryptString(const std::string&amp; 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(&amp;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);
  }
  </code></pre>
  
  <p>so DPAPI is only used when BLOB NOT starts with <code>v10</code> chars. but my cookie BLOBs starts with <code>v10</code> chars, and, according to the code, another crypto-algorithm is used, but i dont understand WHY.</p>