Warm tip: This article is reproduced from stackoverflow.com, please click
node.js cryptography buffer

What is the difference between using string and buffer in Node.js encryption

发布于 2020-03-27 10:25:06

I saw both of the codes below on some websites. One used Buffer to wrap crypto.randomBytes() object for cipher key and used it to concatenate the final result of the encryption, another one used plain crypto.randomBytes() object for cipher key and simply concatenate the final result using 'plus equal' operator.

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");

and...

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

encrypted += cipher.final();

Both implementations work. But I can't find any explanation on why do they use Buffer and don't know what the difference between the two examples is.

UPDATE

I've tried using the same key and iv with both implementations (as Maarten Bodewes suggested, they produce the same result:

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

So, why do one have to use Buffer which looks more complicated to produce the same result?

Questioner
Nawawish Samerpark
Viewed
135
Maarten Bodewes 2019-07-04 05:36

The Buffer is just the internal structure that is used.

Here are some possible advantages:

  • the buffer may store the bytes in machine words (32 or 64 bit) to make the subsequent operations efficient;
  • there is no need to convert back and forth between the buffer and other representations;
  • it may also be more efficient than storage of characters in strings - it may not be clear what the exact way is that those are stored, even if they are just representing bytes (they could use 16 or 32 bit words, for instance, doubling or quadrupling the size required);
  • if there is a conversion error it may also be detected in the explicit conversion function rather than within the encryption method, which could make for easier debugging;
  • it may make it easier to change the code to e.g. use a differently encoded key, e.g. in hexadecimals.

And finally, the Buffer is closer to what a key actually is supposed to be an octet string or byte array, not a textual string.

However, all that said, for simple cryptographic operations there are no differences when it comes to the expected output. So in that sense both methods are valid.