ronomon / crypto-async

Fast, reliable cipher, hash and hmac methods executed in Node's threadpool for multi-core throughput.
MIT License
174 stars 15 forks source link

More documentation #1

Closed chiedo closed 7 years ago

chiedo commented 7 years ago

Howdy!

Thanks for putting this together! This is awesome.

My question is, is there any way you could create some more documentation about each of the parameters or abstract away some of the details here.

I've got AES CBC working with the following function:

/*
 * Encrypts a plaintext using AES CBC
 * @param {Buffer} key
 * @param {Buffer} iv
 * @param {Buffer} plaintext
 * @returns {String}
 */
let encrypt = function(key, iv, plaintext) {
  let encipher = crypto.createCipheriv('aes-256-cbc', key, iv);
  let ciphertext = encipher.update(plaintext, 'binary', 'binary');
  ciphertext += encipher.final('binary');

  return ciphertext;
};

I'm having trouble understanding how I would switch to crypto-async. Obviously, I would need to use a callback, etc. but there are WAY more params in your function.

In regards to encryption and decryption, could you create a wrapper that just accepted the IV, Key and plaintext and output the ciphertext?

Even if you could just add a basic explanation of each, I'm sure I could figure it out from there. Once I did, I could add a wrapper to this repo as a pull request. I'm just having trouble understanding what each param is for.

Thanks again!

jorangreef commented 7 years ago

Thanks @chiedo

Here is an example of using crypto and cryptoAsync. All inputs and outputs are buffers. Binary strings are deprecated by Node as far as I understand, so I changed your example to return a plain buffer.

I will think about adding wrappers which don't take offset and sizes, and which allocate a target buffer automatically (although this would add back slice overhead and unnecessary buffer allocation which were some of the motivations behind crypto-async).

var crypto = require('crypto');
var cryptoAsync = require('crypto-async');

function encrypt(key, iv, plaintext, callback) {
  // Leave more than enough room for block cipher:
  var target = Buffer.alloc(plaintext.length + 64);
  var targetOffset = 0;
  cryptoAsync.cipher(
    'AES-256-CBC',
    1, // encrypt=1, decrypt=0
    key,
    0, // keyOffset
    key.length,
    iv,
    0, // ivOffset
    iv.length,
    plaintext, // source
    0, // sourceOffset
    plaintext.length,
    target,
    targetOffset,
    function(error, targetSize) {
      if (error) return callback(error);
      var ciphertext = target.slice(targetOffset, targetOffset + targetSize);
      callback(undefined, ciphertext);
    }
  );
}

function encryptSync(key, iv, plaintext) {
  var cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
  return Buffer.concat([
    cipher.update(plaintext),
    cipher.final()
  ]);
}

var key = Buffer.alloc(32);
var iv = Buffer.alloc(16);
var plaintext = Buffer.alloc(12);

console.log('encryptSync ciphertext: ' + encryptSync(key, iv, plaintext).toString('hex'));

encrypt(key, iv, plaintext,
  function(error, ciphertext) {
    if (error) throw error;
    console.log('    encrypt ciphertext: ' + ciphertext.toString('hex'));
  }
);
chiedo commented 7 years ago

You're the man! :) This worked like a charm. Thanks for the quick response.

jorangreef commented 7 years ago

Some new easy-to-use methods have been added, see the README and https://github.com/jorangreef/crypto-async/issues/2#issuecomment-269462811 for more.

chiedo commented 7 years ago

VERY nice work @jorangreef