首页 > 解决方案 > 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!

标签: javagoogle-chromeencryptioncookies

解决方案


从 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-simplejna-platformjna

加密的 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 解密。


推荐阅读