1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- /*
- * Copyright 2018 Scytl Secure Electronic Voting SA
- *
- * All rights reserved
- *
- * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
- */
- /* jshint node:true */
- 'use strict';
- var Policy = require('scytl-cryptopolicy');
- var validator = require('./input-validator');
- var codec = require('scytl-codec');
- var sjcl = require('sjcl');
- module.exports = PbkdfDeriver;
- /**
- * @class PbkdfDeriver
- * @classdesc The PBKDF deriver API. To instantiate this object, use the method
- * {@link PbkdfService.newDeriver}.
- * @hideconstructor
- * @param {Policy}
- * policy The cryptographic policy to use.
- */
- function PbkdfDeriver(policy) {
- var keyLength_ = policy.primitives.keyDerivation.pbkdf.keyLengthBytes;
- var minSaltLength_ = policy.primitives.keyDerivation.pbkdf.minSaltLengthBytes;
- var numIterations_ = policy.primitives.keyDerivation.pbkdf.numIterations;
- var hashAlgorithm_ = policy.primitives.keyDerivation.pbkdf.hashAlgorithm;
- /**
- * Derives a key, using a PBKDF.
- *
- * @function derive
- * @memberof PbkdfDeriver
- * @param {string}
- * password The password from which to derive the key.
- * @param {Uint8Array|string}
- * salt The salt from which to derive the key. <b>NOTE:</b> Salt
- * of type <code>string</code> will be UTF-8 encoded.
- * @returns {Uint8Array} The derived key.
- * @throws {Error}
- * If the input data validation fails.
- */
- this.derive = function(password, salt) {
- if (typeof salt === 'string') {
- salt = codec.utf8Encode(salt);
- }
- checkData(password, salt);
- var generateHmac = function(key) {
- var generator = new sjcl.misc.hmac(key, getDigester(hashAlgorithm_));
- this.encrypt = function() {
- return generator.encrypt.apply(generator, arguments);
- };
- };
- // NOTE: The following Base64 encoding/decoding should be replaced with the
- // use of 'sjcl.codec.bytes.toBits/fromBits' when/if the latter becomes part
- // of the default sjcl build.
- var derivedKey = sjcl.misc.pbkdf2(
- password, sjcl.codec.base64.toBits(codec.base64Encode(salt)),
- numIterations_, keyLength_ * 8, generateHmac);
- return codec.base64Decode(sjcl.codec.base64.fromBits(derivedKey));
- };
- function getDigester(algorithm) {
- if (algorithm ===
- Policy.options.primitives.keyDerivation.pbkdf.hashAlgorithm.SHA256) {
- return sjcl.hash.sha256;
- } else {
- throw new Error(
- 'Hash algorithm \'' + algorithm + '\' is not recognized.');
- }
- }
- function checkData(password, salt) {
- validator.checkIsType(
- password, 'string', 'Password from which to derive key');
- validator.checkIsInstanceOf(
- salt, Uint8Array, 'Uint8Array', 'Salt from which to derive key');
- if (salt.length < minSaltLength_) {
- throw new Error(
- 'The salt byte length ' + salt.length +
- ' is less than the minimum allowed salt length ' + minSaltLength_ +
- ' set by the cryptographic policy.');
- }
- }
- }
|