1.0.3 • Published 9 years ago

key-derivation v1.0.3

Weekly downloads
1
License
MIT
Repository
github
Last release
9 years ago

Key Derivation Functions

This package is a wrapper around different key derivation functions (password hashing functions, for the unintiated) presenting a single and consistent API around different ways to "hash" secrets.

Install and use

Install as usual with NPM:

npm install --save key-derivation

You can use it with callbacks...

var KDF = require('key-derivation');

// Create a KDF and derive a key
new KDF(spec).deriveKey(secret, salt, callback(err, result) {
  // Look, ma! We hashed the secret
});

... or with a Promise:

var KDF = require('key-derivation');

// Create a KDF and derive a key
new KDF(spec).promiseKey(secret, salt).then(function(result) {
  // Look, ma! We hashed the secret
  })
});

API Description

A KDF can be constructed in three ways:

  • Using defaults, by just calling new KDF()
  • Using an algorithm identifier (one of BCRYPT PBKDF2 or SCRYPT case insensitive).
  • Using a KDF spec enclosing the algorithm and its parameters.

Key derivation with callbacks

kdf.deriveKey(secret, salt, function callback(error, result) {
  ...
})

The deriveKey(...) function takes three arguments:

  • secret: a string or Buffer containing the data to be hashed.
  • salt: the optional salt for the computation; if unspecified a random one will be generated (again a string or Buffer).
  • callback: a callback function invoked with the two usual error and result arguments.

Key derivation with promises

kdf.promiseKey(secret, salt)
  .then(function(result) { ... })
  .catch(function(error) { ... })

The deriveKey(...) function takes two arguments:

  • secret: a string or Buffer containing the data to be hashed.
  • salt: the optional salt for the computation; if unspecified a random one will be generated (again a string or Buffer).

Other properties and methods

var KDF = require('key-derivation');
KDF.defaultSpec;

The static immutable defaultSpec property of the KDF class contains the base KDF spec that will be used when invoking the constructor without (or only partial) arguments.

var kdf = new KDF(spec);
console.log(kdf.kdfSpec);

The kdfSpec immutable property of each KDF instance will contain the full KDF spec used by the deriveKey(...) and promiseKey(...) functions.

var kdf = new KDF(spec).withSecureRandom();

KDF instances are constructed by default with a non-failing pseudo random number generation (as secure random number generations might generate errors).

The withSecureRandom() function invked without parameters will instruct the KDF instance to use a (potentially failing) cryptographically secure random number generator.

The optional boolean parameter to this method allows specific enabling or disabling of this feature.

See the documentation for Node's crypto module, and the difference between its randomBytes(...) and pseudoRandomBytes(...) for the difference.

This function always returns the same KDF instance it was called on.

String encoding

Both the secret and salt can be specified as Buffer or string.

When using a string, its value will be converted internally into a Buffer using the UTF8 encoding.

Result structure

The result produced by the key derivation operations described above will be an object containing the following keys:

  • derived_key: the Buffer containing the bytes of the derived key
  • salt: the Buffer containing the bytes of the salt, either the specified one or the randomly generated one.
  • kdf_spec: a complete KDF spec describing the key derivation computation.

For example:

{
  'derived_key': Buffer([ ... ]),
  'salt': Buffer([ ... ]),
  'kdf_spec': {
    'algorithm': 'SCRYPT',
    'hash': 'SHA256',
    'cpu_memory_cost': 32768,
    'block_size': 8,
    'parallelization': 1,
    'derived_key_length': 32
  }
}

Algorithms and KDF specs

Bcrypt

PLEASE NOTE that due to the current limitations of Node's bcrypt library we are currently unable to support reliable pre-hashing of secrets, henceforth the input will always be limited to 72 characters.

Furthermore extreme care should be used when using this method, as internally the extensive use of string does not allow processing of non-UTF8 sequence of bytes.

Defaults:

{
  "algorithm": "BCRYPT",
  "rounds": 10
}

The BCRYPT algorithm KDF spec contains two keys:

  • algorithm: always BCRYPT
  • rounds: the usual Blowfish log2(iterations) (between 4 and 31)

The BCRYPT requirements dictate a salt of precisely 16 bytes, and the derived_key will always be precisely 23 bytes. Any secret whose length (the number of bytes, take this into consideration with UTF8 strings) is greater than 72 characters will be truncated.

PBKDF2

Defaults:

{
  "algorithm": "PBKDF2",
  "hash": "SHA256",
  "iterations": 65536,
  "derived_key_length": 32
}

The PBKDF2 algorithm KDF spec contains four keys:

  • algorithm: always PBKDF2
  • hash: the hasing function to use for deriving the key
  • iterations: the number of iterations
  • derived_key_length: the desired number of bytes in the output key (defaults to the number of bytes produced by the hasing function).

When unspecified, the number of bytes randomly generated for the salt will be equal to the number of bytes produced by the hashing function.

See RFC 2898 for more information.

Scrypt

PLEASE NOTE that due to the current limitations of Node's scrypt library we are currently only able to support SHA256 as a hashing function.

Defaults:

{
  "algorithm": "SCRYPT",
  "hash": "SHA256",
  "cpu_memory_cost": 32768,
  "parallelization": 1,
  "block_size": 8,
  "derived_key_length": 32
}

The PBKDF2 algorithm KDF spec contains four keys:

  • algorithm: always SCRYPT
  • hash: the hasing function to use for deriving the key
  • cpu_memory_cost: the CPU/memory cost parameter N
  • parallelization: the parallelization factor p
  • block_size: the block size parameter b
  • derived_key_length: the desired number of bytes in the output key (defaults to the number of bytes produced by the hasing function).

When unspecified, the number of bytes randomly generated for the salt will be equal to the number of bytes produced by the hashing function.

See TarSnap for more information.

License (MIT)

Copyright (c) 2015 USRZ.com and Pier Paolo Fumagalli

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.