Node.js 加密Cookie并保存到Chrome

Node.js 加密Cookie并保存到Chrome,node.js,google-chrome,encryption,cookies,cryptography,Node.js,Google Chrome,Encryption,Cookies,Cryptography,我目前正在编写Node.js脚本,该脚本将我登录到一个网站,并在我登录时自动打开浏览器。 我一直在尝试向chrome的“cookie”数据库添加cookie(从登录后请求中收集),但未能正确加密。 Stackoverflow线程,关于Cookie的加密,我是这样来的: 但是这个线程是关于解密cookie而不是加密它 function encryptCookie(cookie, key){ const iv = crypto.randomBytes(16); let cipher

我目前正在编写Node.js脚本,该脚本将我登录到一个网站,并在我登录时自动打开浏览器。 我一直在尝试向chrome的“cookie”数据库添加cookie(从登录后请求中收集),但未能正确加密。 Stackoverflow线程,关于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仍然太短

我知道我可以使用webscraper或只是在页面上保护我的密码,但我想与cookie数据库和HTTP请求交互。

中的数据结构描述如下:

加密数据以v10的ASCII编码开始(即。 0x763130),后跟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字节。

Wow,感谢您快速而详细的回答!我一定会按照你推荐的方式来尝试。我以前从未加密/解密过,再次感谢您的帮助。一旦我有时间做这个项目(最有可能在大约10小时内),我会再次评论这篇文章。