java - Java - 如何解密 Chrome cookie?
问题描述
我正在尝试从 Chrome 浏览器中提取 cookie。我发现这篇文章阅读和插入 Chrome Cookies Java 它从用户浏览器获取 cookie。问题是它不起作用。这部分代码抛出异常:
System.setProperty("jna.predictable_field_order","true");
decryptedBytes = Crypt32Util.cryptUnprotectData(encryptedCookie.getEncryptedValue());
com.sun.jna.platform.win32.Win32Exception: Недопустимые данные.
at com.sun.jna.platform.win32.Crypt32Util.cryptUnprotectData(Crypt32Util.java:128)
at com.sun.jna.platform.win32.Crypt32Util.cryptUnprotectData(Crypt32Util.java:103)
at com.sun.jna.platform.win32.Crypt32Util.cryptUnprotectData(Crypt32Util.java:90)
at CookieExtractor.CookieExtractor$ChromeBrowser.decrypt(CookieExtractor.java:486)
at CookieExtractor.CookieExtractor$ChromeBrowser.processCookies(CookieExtractor.java:448)
at CookieExtractor.CookieExtractor$Browser.getCookiesForDomain(CookieExtractor.java:256)
at CookieExtractor.CookieExtractor.getCookie(CookieExtractor.java:50)
at CookieExtractor.CookieExtractor.main(CookieExtractor.java:38)
我开始挖掘如何解密 Chrome cookie 并找到了这个 jar http://jdpapi.sourceforge.net/但它也不起作用,因为这个 jar 不能与 64 位操作系统一起使用。所以我真的很困惑如何从 Chrome 中解密 cookie。
任何帮助appriciated!
解决方案
从 Chrome v80.0 开始,cookie 使用 AES GCM 加密,请参见此处。密钥使用 DPAPI 加密。以下假设是 Windows 7/8/10 操作系统。
首先,必须从本地状态JSON 文件中读取密钥并使用 DPAPI 解密。一个可能的 Java 实现是:
import java.util.Arrays;
import java.util.Base64;
import java.io.FileReader;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import com.sun.jna.platform.win32.Crypt32Util;
...
// Get encrypted master key
String pathLocalState = System.getProperty("user.home") + "/AppData/Local/Google/Chrome/User Data/Local State";
JSONObject jsonObjectLocalState = (JSONObject)new JSONParser().parse(new FileReader(pathLocalState));
String encryptedMasterKeyWithPrefixB64 = (String)((JSONObject)jsonObjectLocalState.get("os_crypt")).get("encrypted_key");
// Remove praefix (DPAPI)
byte[] encryptedMasterKeyWithPrefix = Base64.getDecoder().decode(encryptedMasterKeyWithPrefixB64);
byte[] encryptedMasterKey = Arrays.copyOfRange(encryptedMasterKeyWithPrefix, 5, encryptedMasterKeyWithPrefix.length);
// Decrypt
byte[] masterKey = Crypt32Util.cryptUnprotectData(encryptedMasterKey);
使用json-simple、jna-platform和jna。
加密的 cookie 由 3 个字节的前缀(v10的 ASCII 编码)、12 个字节的随机数以及密文和标签组成。由于在 Java 中密文和标签是以连接形式处理的,因此只需要将 nonce 和密文/标签分开。之后,可以执行解密。Java中可能的实现是:
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
...
byte[] encryptedCookie = new byte[] {0x76, 0x31, 0x30, ...}; // may contain the encrypted cookie
// Separate praefix (v10), nonce and ciphertext/tag
byte[] nonce = Arrays.copyOfRange(encryptedCookie, 3, 3 + 12);
byte[] ciphertextTag = Arrays.copyOfRange(encryptedCookie, 3 + 12, encryptedCookie.length);
// Decrypt
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, nonce);
SecretKeySpec keySpec = new SecretKeySpec(masterKey, "AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
byte[] cookie = cipher.doFinal(ciphertextTag);
请注意,只有使用 Chrome v80.0 或更高版本加密的 cookie 才能以这种方式解密。使用早期 Chrome 版本加密的 Cookie 必须使用 DPAPI 解密。
推荐阅读
- python - 如果最后一个变量是空字符串,则调整字符串的格式化模式
- package - 为什么我无法在 Common Lisp 中读取此文件?
- google-sheets - 如何在 Google 表格的过滤器匹配公式中动态获取单元格值?
- reactjs - Tailwind 断点不适用于 Next.js SSG
- python - 如何处理这些数据集以创建 datasetDict?
- python - AttributeError:“列表”对象没有属性“data_filter”
- android - 不同productFlavors的Android替代xml资源文件
- powershell - 在移动文件之前寻求Powershell函数来检查多个文件夹是否存在
- c - 如何使用函数返回初始化结构成员?
- r - 是否有用于计算 df 中每一行的 Spearman 相关系数并将其写为向量的 R 函数?