加密 Cookie 并保存到 Chrome

3

我目前正在开发一个Node.js脚本,可以让我登录一个网站并自动在浏览器中保持登录状态。我一直在尝试将从登录POST请求中获取的cookie添加到Chrome的“cookie”数据库中,但我无法正确加密它。我找到了一个关于Cookie加密的Stackoverflow帖子:Chrome 80如何解密cookie,但该帖子是关于解密cookie而不是加密。

function encryptCookie(cookie, key){
    const iv = crypto.randomBytes(16);
    let cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
    let encrypted = cipher.update(cookie);
    encrypted = Buffer.concat([Buffer.from('v10'), encrypted, cipher.final()]);
    console.log(`Encrypted: ${encrypted}`);
    return encrypted; 
}

至于“密钥”,我正在使用本地状态下解密后的密钥。(我使用DPAPI模块解密了密钥。)我知道加密的cookie始终以v10开头,因此我将其作为前缀添加,但加密的Cookie仍然太短。

我知道我可以使用网络爬虫或只是在页面上保存我的密码,但我想与cookie数据库和HTTP请求进行交互。

1个回答

3
链接的答案中,数据的结构描述如下:
引用:

加密数据以v10(即0x763130)的ASCII编码开头,后跟12个字节的nonce、实际密文和最后16个字节的身份验证标记。

即数据结构如下:
  • 3个字节的前缀v10
  • 12个字节的IV
  • 密文
  • 16个字节的身份验证标记
长度为:3 + 12 + 密文长度 + 16。此外,在GCM模式下不使用填充,因此密文的长度与明文相同。
此外,发布的代码使用了错误的IV长度,没有连接IV并且没有考虑身份验证标记。
加密/解密的一种可能的实现方式是:
var crypto = require('crypto');

function encryptCookie(cookie, key){
    const iv = crypto.randomBytes(12);
    const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
    const encryptedCookie = Buffer.concat(
      [
        Buffer.from('v10'),         // prefix
        iv,                         // 12 bytes nonce
        cipher.update(cookie),      // cookie data
        cipher.final(), 
        cipher.getAuthTag()         // 16 bytes authentication
      ]);
    return encryptedCookie; 
}

function decryptCookie(encryptedCookie, key){
    const prefix = encryptedCookie.slice(0, 3);                                     // prefix
    const iv = encryptedCookie.slice(3, 3 + 12);                                    // 12 bytes nonce
    const ciphertext = encryptedCookie.slice(3 + 12, encryptedCookie.length - 16);  // encrypted cookie
    const authTag = encryptedCookie.slice(encryptedCookie.length - 16);             // 12 bytes authentication tag
    const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
    decipher.setAuthTag(authTag);
    const decryptedCookie = Buffer.concat(
      [
        decipher.update(ciphertext),      // encrypted cookie
        decipher.final(), 
      ]);
    return decryptedCookie; 
}

// Encryption
const cookie = Buffer.from('The test cookie with some data');
const key = Buffer.from('01234567890123456789012345678901');
const encryptedCookie = encryptCookie(cookie, key);
console.log(encryptedCookie);
console.log(encryptedCookie.length);

// Decryption
const decryptedCookie = decryptCookie(encryptedCookie, key);
console.log(decryptedCookie.toString('utf8'));

对于长度为30字节的样本cookie,加密数据的长度为3 + 12 + 30 + 16 = 61字节。

哇,感谢您快速而详细的回答!我一定会按照您推荐的方式尝试。我以前从未进行过加密/解密操作,所以再次感谢您的帮助。一旦我有时间处理这个项目(大约10小时后),我会再次在帖子上发表评论。 - SleepySloth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接