123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- /*
- * 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, jasmine:true */
- 'use strict';
- var cryptoPolicy = require('scytl-cryptopolicy');
- var pbkdf = require('../lib/index');
- var codec = require('scytl-codec');
- var forge = require('node-forge');
- describe('The PBKDF module should be able to ...', function() {
- var PASSWORD = 'Test';
- var SALT = 'TestTestTestTestTestTestTestTest';
- var salt_;
- var tooSmallsalt_;
- var deriver_;
- var key_;
- var policy_;
- beforeAll(function() {
- salt_ = codec.utf8Encode(SALT);
- tooSmallsalt_ = codec.utf8Encode('1');
- deriver_ = pbkdf.newService().newDeriver();
- key_ = deriver_.derive(PASSWORD, salt_);
- });
- beforeEach(function() {
- policy_ = cryptoPolicy.newInstance();
- });
- describe('create a PBKDF service that should be able to ..', function() {
- describe('create a PBKDF deriver that should be able to', function() {
- it('derive a key of the expected length, when using the default cryptographic policy.',
- function() {
- var key = deriver_.derive(PASSWORD, salt_);
- expect(key).toBeDefined();
- expect(key.length)
- .toBe(policy_.primitives.keyDerivation.pbkdf.keyLengthBytes);
- });
- it('derive a key of the expected length, when using a specified cryptographic policy.',
- function() {
- policy_.primitives.keyDerivation.pbkdf.keyLengthBytes =
- cryptoPolicy.options.primitives.keyDerivation.pbkdf
- .keyLengthBytes.KL_32;
- var pbkdfService = pbkdf.newService({policy: policy_});
- var key = pbkdfService.newDeriver().derive(PASSWORD, salt_);
- expect(key).toBeDefined();
- expect(key.length)
- .toBe(cryptoPolicy.options.primitives.keyDerivation.pbkdf
- .keyLengthBytes.KL_32);
- });
- it('derive the same key every time, for a given cryptographic policy.',
- function() {
- var key = deriver_.derive(PASSWORD, salt_);
- expect(key).toBeDefined();
- expect(key).toEqual(key_);
- });
- it('derive the expected key if salt is provided as string instead of bytes',
- function() {
- var key = deriver_.derive(PASSWORD, SALT);
- expect(key).toBeDefined();
- expect(key).toEqual(key_);
- });
- it('derive different keys when different numbers of iterations are specified.',
- function() {
- policy_.primitives.keyDerivation.pbkdf.numIterations =
- cryptoPolicy.options.primitives.keyDerivation.pbkdf.numIterations
- .I_1;
- var pbkdfService = pbkdf.newService({policy: policy_});
- var key = pbkdfService.newDeriver().derive(PASSWORD, salt_);
- expect(key).toBeDefined();
- expect(key).not.toEqual(key_);
- });
- it('derive different keys when different passwords are used.',
- function() {
- var key = deriver_.derive(PASSWORD + 'a', salt_);
- expect(key).toBeDefined();
- expect(key).not.toEqual(key_);
- });
- it('derive different keys when different salts are used.', function() {
- var key = deriver_.derive(PASSWORD, codec.utf8Encode(SALT + 'a'));
- expect(key).toBeDefined();
- expect(key).not.toEqual(key_);
- });
- it('derive the same key for the SJCL and Forge cryptographic service providers, given a random password.',
- function() {
- var password =
- generateRandomString(Math.floor(Math.random() * 128) + 1);
- // Derive key using SJCL.
- var derivedKeyFromSjcl = deriver_.derive(password, salt_);
- // Derive key using Forge.
- var numIterations =
- policy_.primitives.keyDerivation.pbkdf.numIterations;
- var keyLengthBytes =
- policy_.primitives.keyDerivation.pbkdf.keyLengthBytes;
- var derivedKeyFromForgeBinaryEncoded = forge.pkcs5.pbkdf2(
- codec.binaryEncode(codec.utf8Encode(password)),
- codec.binaryEncode(salt_), numIterations, keyLengthBytes,
- getHashGenerator(
- policy_.primitives.keyDerivation.pbkdf.hashAlgorithm,
- cryptoPolicy.options.primitives.keyDerivation.pbkdf
- .hashAlgorithm));
- var derivedKeyFromForge =
- codec.binaryDecode(derivedKeyFromForgeBinaryEncoded);
- expect(derivedKeyFromForge).toEqual(derivedKeyFromSjcl);
- });
- it('throw an error when a salt length less than the minimum value specified in the cryptographic policy is used',
- function() {
- expect(function() {
- deriver_.derive(PASSWORD, tooSmallsalt_);
- }).toThrow();
- });
- });
- });
- });
- function generateRandomString(length) {
- var allowedChars =
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,-./:;<=>?@[\]^_`{|}~';
- var str = '';
- for (var i = 0; i < length; i++) {
- str += allowedChars.charAt(Math.floor(Math.random() * allowedChars.length));
- }
- return str;
- }
- function getHashGenerator(algorithm, config) {
- if (algorithm === config.SHA256) {
- return forge.sha256.create();
- } else {
- throw 'Hash algorithm \'' + algorithm + '\' is unsupported';
- }
- }
|