尝试解密Chrome Cookie时,DPAPI失败,并出现CryptographicException [英] DPAPI fails with CryptographicException when trying to decrypt Chrome cookies

查看:65
本文介绍了尝试解密Chrome Cookie时,DPAPI失败,并出现CryptographicException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从Chrome浏览器获取会话.我可以在开发人员工具中看到2个cookie文件.但这对于用户从浏览器获取cookie值很不方便,我想在代码中做到这一点.因此,我使用此代码来获取Chrome默认配置文件Cookie sqlite DB:

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 = @"Google\Chrome\User Data\Default\Cookies";

path = Path.Combine(local, path);

接下来我创建SQLite连接并请求

next i create SQLite connection and request

var cmd = new SQLiteCommand("SELECT encrypted_value, name FROM cookies WHERE host_key = 'my_host_ip'", con);

然后我阅读了结果

byte[] encryptedCookie = (byte[])r.GetValue(r.GetOrdinal("encrypted_value"));

并尝试对其解密:

var decodedData = ProtectedData.Unprotect(encryptedCookie, null, DataProtectionScope.CurrentUser);
var plainText = Encoding.ASCII.GetString(decodedData);

在这里我有例外

System.Security.Cryptography.CryptographicException

我知道我必须在启动浏览器的同一用户帐户(在同一台计算机上)下解密cookie内容,并且为此参数使用 DataProtectionScope.CurrentUser

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

我在调试器中看到了63个字节(在 encryptedCookie 数组中),我还在SQLite DB BLOB字段中看到了这个字节.但是 Unprotect 方法会引发 System.Security.Cryptography.CryptographicException:无效数据错误.

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.

我的代码在我办公室的5台不同PC(win10,win7)上都能正常工作,但在我的开发人员PC(win10,vs2019)上却无法正常工作.

my code works fine at 5 different PC's in my office (win10, win7), but didnt work on my developer PC (win10, vs2019).

我认为问题出在我的Windows设置或其他地方,而不是我的代码中.所以我做错了吗?

i think that the problem is in my Windows Settings or somewhere else, not in my code. so what i am doing wrong?

有趣的注释-我发现执行相同功能的PowerShell脚本(通过 Add-Type -AssemblyName System.Security )-获取cookie并解密.该脚本在5台办公室PC上也可以正常工作,但在我的PC上却不起作用.

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.

我的Windows安装是新的,我没有AV软件.我们已连接到相同的Corporate域,并且具有相同的安全设置.

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 一点刺激:

  1. 从Chrome浏览器中获取cookie值(32个字符,JSESSIONID)
  2. 创建一个简单的应用程序,该应用程序使用 CurrentUser 保护范围来保护此值.现在我有一个178个字节的数组(结果#1)
  3. 使用a) https://sqliteonline.com/和b)DataBase.Net桌面查看Chrome的cookie数据库.应用程序.这两种方法给我相同的结果:只有63个字节的加密cookie数据(结果#2).我也可以使用 System.Data.SQLite
  4. 在c#应用程序中获得相同的结果
  1. get cookie value from Chrome browser (32 chars, JSESSIONID)
  2. create a simple app that protects this value with CurrentUser protection scope. now i have an array of 178 bytes (result #1)
  3. 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

因此,结果的长度或内容不相等结果#1!=结果#2

so, the results are not equal in length or content result #1 != result #2

看起来Chrome的cookie值受不同范围(也许是管理员帐户)保护,但是我在Chrome的进程中的任务管理器中看到了我的用户帐户名

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.我使用.net 4.7.2

P.S. i use .net 4.7.2

UPD 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仅在BLOB NOT以 v10 字符开头时使用.但是我的cookie BLOB以 v10 字符开头,并且根据代码,使用了另一个加密算法,但是我不明白为什么.

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.

推荐答案

我终于知道了.根据Chromium的消息来源,使用了两种方法来解密cookie值.

I finally figured it out. according to Chromium sources, two methods are used to decrypt the cookie value.

  1. 如果cookie值以 v10 字符开头,则我们使用 AES_256_GCM
  2. 否则,将使用 DPAPI
  1. if the cookie value starts with v10 chars, we use AES_256_GCM
  2. otherwise, DPAPI is used

对于第一种方法,我们需要密钥和随机数.密钥位于Google Chrome文件中,随机数位于加密的cookie值中.

for the first method we need key and nonce. key is located in Google Chrome files and nonce is located in encrypted cookie value.

我仍然不清楚-是什么决定使用哪种方法

it remains unclear for me - what determines which method is used

这篇关于尝试解密Chrome Cookie时,DPAPI失败,并出现CryptographicException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆