温馨提示:本文翻译自stackoverflow.com,查看原文请点击:cryptography - What is the difference between using string and buffer in Node.js encryption
node.js cryptography buffer

cryptography - 在Node.js加密中使用字符串和缓冲区有什么区别

发布于 2020-03-27 11:28:06

我在某些网站上看到了下面的两个代码。一个用于Buffercrypto.randomBytes()对象包装为密钥,然后将其用于连接加密的最终结果,另一个用于将普通crypto.randomBytes()对象用于密钥,并仅使用“加等于”运算符将最终结果进行连接。

const cipher = crypto.createCipheriv(
  "aes-256-gcm",
  Buffer.from(crypto.randomBytes(32)),
  crypto.randomBytes(16)
);
let encrypted = cipher.update("this is data");

encrypted = Buffer.concat([encrypted, cipher.final()]);
// edited: I forgot below line
encrypted = encrypted.toString("hex");

和...

const cipher = crypto.createCipheriv(
  "aes-256-gcm",
  crypto.randomBytes(32),
  crypto.randomBytes(16)
);
let encrypted = cipher.update("this is data");

encrypted += cipher.final();

两种实现均有效。但是我找不到任何关于为什么使用它们的解释,Buffer也不知道两个示例之间的区别。

更新

我已经使用相同的尝试key,并iv有两种实现(如马腾Bodewes 建议,它们产生相同的结果:

const crypto = require('crypto');

const data = 'hello world'
const algorithm = 'aes-256-gcm'
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);

function encrypt1(data) {
    const cipher = crypto.createCipheriv(algorithm, key, iv);
    let encrypted = cipher.update(data, 'utf8', 'hex');

    encrypted += cipher.final('hex');

    return encrypted;
}

function encrypt2(data) {
    const cipher = crypto.createCipheriv(algorithm, Buffer.from(key), iv);
    let encrypted = cipher.update(data);

    encrypted = Buffer.concat([encrypted, cipher.final()]);

    return encrypted.toString('hex');
}

const result1 = encrypt1(data);
const result2 = encrypt2(data);

console.log('result1: ', result1); // -> result1:  501db5c82e79e3185c1601
console.log('result2: ', result2); // -> result2:  501db5c82e79e3185c1601

那么,为什么必须使用看起来更复杂的Buffer才能产生相同的结果呢?

查看更多

查看更多

提问者
Nawawish Samerpark
被浏览
170
Maarten Bodewes 2019-07-04 05:36

Buffer只是所使用的内部结构。

以下是一些可能的优点:

  • 缓冲器可以将字节以机器字(32或64位)存储,以使后续操作高效。
  • 无需在缓冲区和其他表示之间来回转换;
  • 它可能比存储字符串中的字符更有效-可能不清楚存储这些字符的确切方式,即使它们只是表示字节(它们可以使用16或32位字,例如,加倍或所需大小增加三倍);
  • 如果存在转换错误,也可以在显式转换函数中而不是在加密方法中检测到,这可以使调试更容易;
  • 这样可以更容易地将代码更改为例如使用不同的编码密钥(例如以十六进制表示)。

最后,Buffer它更接近于键实际上应该是八位字节字符串字节数组,而不是文本字符串的键

但是,所有这些都表明,对于简单的密码操作,在预期输出方面没有区别。因此从这个意义上讲,这两种方法都是有效的。