credential-plus-pbkdf2
Advanced tools
Comparing version 1.0.2 to 2.0.0
92
index.js
@@ -10,3 +10,4 @@ 'use strict'; | ||
* Default configurations used to generate a new hash. | ||
* @type {Object} | ||
* @private | ||
* @type {object} | ||
*/ | ||
@@ -32,3 +33,3 @@ const defaultConfigs = { | ||
* using Node's built-in crypto.randomBytes(). | ||
* | ||
* @private | ||
* @param {number} length The length of the salt to be generated. | ||
@@ -48,32 +49,30 @@ * @param {function} callback Called after the salt has been generated. | ||
* Generates an unique hash and the data needed to verify it. | ||
* @public | ||
* @param {string} password The password to hash. | ||
* @param {object} configs Configurations related to the hashing function. | ||
* @param {generateCallback} callback Called after the hash has been generated. | ||
* @param {object} configs Configurations related to the hashing function. | ||
* @returns {Promise<string>} A promise that contains the generated hash string. | ||
*/ | ||
/** | ||
* @callback generateCallback | ||
* @param {object} err Possible error thrown. | ||
* @param {string} hash Generated hash string. | ||
*/ | ||
function hashFunc(password, configs, callback) { | ||
const cfgs = _.extend(defaultConfigs, configs); | ||
function hashFunc(password, configs) { | ||
return new Promise((resolve, reject) => { | ||
const cfgs = _.extend(defaultConfigs, configs); | ||
createSalt(cfgs.keylen, (err, salt) => { | ||
if (err) { | ||
callback(err); | ||
return; | ||
} | ||
crypto.pbkdf2(password, salt, cfgs.iterations, cfgs.keylen, cfgs.digest, (err, hash) => { | ||
createSalt(cfgs.keylen, (err, salt) => { | ||
if (err) { | ||
callback(err); | ||
reject(err); | ||
return; | ||
} | ||
const data = { | ||
secret: hash.toString('base64'), | ||
salt, | ||
iterations: cfgs.iterations, | ||
keylen: cfgs.keylen, | ||
digest: cfgs.digest | ||
}; | ||
callback(null, JSON.stringify(data)); | ||
crypto.pbkdf2(password, salt, cfgs.iterations, cfgs.keylen, cfgs.digest, (err, hash) => { | ||
if (err) { | ||
reject(err); | ||
return; | ||
} | ||
const data = { | ||
secret: hash.toString('base64'), | ||
salt, | ||
iterations: cfgs.iterations, | ||
keylen: cfgs.keylen, | ||
digest: cfgs.digest | ||
}; | ||
resolve(JSON.stringify(data)); | ||
}); | ||
}); | ||
@@ -85,25 +84,24 @@ }); | ||
* Determines whether or not the user's input matches the stored password. | ||
* @param {object} hash Previously hashed password. | ||
* @param {password} password User's password input. | ||
* @param {hashCallback} callback Called after the hash has been computed. | ||
* @public | ||
* @param {string} hash Stringified hash object generated from this package. | ||
* @param {string} input User's password input. | ||
* @returns {Promise<boolean>} A promise that contains a boolean that is true if | ||
* if the hash computed for the input matches. | ||
*/ | ||
/** | ||
* @callback hashCallback | ||
* @param {object} err Possible error thrown. | ||
* @param {string} match True if the hash computed for the input matches. | ||
*/ | ||
function verifyFunc(hash, password, callback) { | ||
let hashObj; | ||
try { | ||
hashObj = JSON.parse(hash); | ||
} catch (err) { | ||
return callback(new Error('Couldn\'t parse the provided hash.')); | ||
} | ||
crypto.pbkdf2(password, hashObj.salt, hashObj.iterations, hashObj.keylen, hashObj.digest, (err, pwdHash) => { | ||
if (err) { | ||
callback(err); | ||
return; | ||
function verifyFunc(hash, password) { | ||
return new Promise((resolve, reject) => { | ||
let hashObj; | ||
try { | ||
hashObj = JSON.parse(hash); | ||
} catch (err) { | ||
return reject(new Error('Couldn\'t parse the provided hash.')); | ||
} | ||
const match = tsse(pwdHash.toString('base64'), hashObj.secret); | ||
callback(null, match); | ||
crypto.pbkdf2(password, hashObj.salt, hashObj.iterations, hashObj.keylen, hashObj.digest, (err, pwdHash) => { | ||
if (err) { | ||
reject(err); | ||
return; | ||
} | ||
const match = tsse(pwdHash.toString('base64'), hashObj.secret); | ||
resolve(match); | ||
}); | ||
}); | ||
@@ -110,0 +108,0 @@ } |
{ | ||
"name": "credential-plus-pbkdf2", | ||
"version": "1.0.2", | ||
"version": "2.0.0", | ||
"description": "pbkdf2 hash function implementation for credential-plus", | ||
@@ -14,5 +14,4 @@ "main": "index.js", | ||
"nyc": "^11.0.3", | ||
"pify": "^3.0.0", | ||
"xo": "*", | ||
"credential-plus": "*" | ||
"credential-plus": "2.x" | ||
}, | ||
@@ -19,0 +18,0 @@ "engines": { |
156
README.md
@@ -1,9 +0,24 @@ | ||
# credential-plus-pbkdf2 | ||
[![Travis CI](https://travis-ci.org/simonepri/credential-plus-pbkdf2.svg?branch=master)](https://travis-ci.org/simonepri/credential-plus-pbkdf2) [![Codecov](https://img.shields.io/codecov/c/github/simonepri/credential-plus-pbkdf2/master.svg)](https://codecov.io/gh/simonepri/credential-plus-pbkdf2) [![npm](https://img.shields.io/npm/dm/credential-plus-pbkdf2.svg)](https://www.npmjs.com/package/credential-plus-pbkdf2) [![npm version](https://img.shields.io/npm/v/credential-plus-pbkdf2.svg)](https://www.npmjs.com/package/credential-plus-pbkdf2) [![npm dependencies](https://david-dm.org/simonepri/credential-plus-pbkdf2.svg)](https://david-dm.org/simonepri/credential-plus-pbkdf2) [![npm dev dependencies](https://david-dm.org/simonepri/credential-plus-pbkdf2/dev-status.svg)](https://david-dm.org/simonepri/credential-plus-pbkdf2#info=devDependencies) | ||
> 🛡 pbkdf2 plugin for credential-plus | ||
<h1 align="center"> | ||
<img src="https://github.com/simonepri/credential-plus/blob/master/media/credential-plus.png?raw=true" alt="credential-plus-pbkdf2" /> | ||
</h1> | ||
<div align="center"> | ||
<a href="https://travis-ci.org/simonepri/credential-plus-pbkdf2"> <img src="https://travis-ci.org/simonepri/credential-plus-pbkdf2.svg?branch=master" alt="build status"></a> | ||
<a href="https://codecov.io/gh/simonepri/credential-plus-pbkdf2"><img src="https://img.shields.io/codecov/c/github/simonepri/credential-plus-pbkdf2/master.svg" alt="code coverage" /></a> | ||
<a href="https://github.com/sindresorhus/xo"><img src="https://img.shields.io/badge/code_style-XO-5ed9c7.svg" alt="code style" /></a> | ||
<a href="https://www.npmjs.com/package/credential-plus-pbkdf2"><img src="https://img.shields.io/npm/v/credential-plus-pbkdf2.svg" alt="npm version" /></a> | ||
<a href="https://www.npmjs.com/package/credential-plus-pbkdf2"><img src="https://img.shields.io/npm/dm/credential-plus-pbkdf2.svg" alt="npm downloads" /></a> | ||
<a href="https://david-dm.org/simonepri/credential-plus-pbkdf2"><img src="https://david-dm.org/simonepri/credential-plus-pbkdf2.svg" alt="dependencies" /></a> | ||
<a href="https://david-dm.org/simonepri/credential-plus-pbkdf2#info=devDependencies"><img src="https://david-dm.org/simonepri/credential-plus-pbkdf2/dev-status.svg" alt="dev dependencies" /></a> | ||
<a href="LICENSE"><img src="https://img.shields.io/github/license/simonepri/credential-plus-pbkdf2.svg" alt="license" /></a> | ||
</div> | ||
<br /> | ||
<div align="center"> | ||
🛡 PBKDF2 password hashing function for [credential-plus](https://github.com/simonepri/credential-plus). | ||
</div> | ||
<div align="center"> | ||
<sub> | ||
If you find a security flaw in this code, PLEASE [report it](issues/new). | ||
</sub> | ||
</div> | ||
This package is thought to be used in conjunction with [credential-plus](https://github.com/simonepri/credential-plus) | ||
If you find a security flaw in this code, please [report it](issues/new). | ||
## Install | ||
@@ -21,115 +36,32 @@ | ||
// Hash and verify with pbkdf2 and default configs | ||
credential.hash('We are all unicorns', {func: 'pbkdf2'}, (err, hash) => { | ||
console.log(hash); | ||
//=> {"hash":"{\"secret\":\"fo3R+bNr2guklSeg1FGoWGIpyrDQ03aPeoTxP90zkVWAISZFIO5S0qQTZtmAAyrmzJFEPdDxK6BX3P3jo+MtG+Fvk5qr+Tfrx2QqemQjrJOLN506SxnqvVs1tlm81QteAgZ5/ZCA55Onv5W9f/EkxgSyrCyqcdkKi/KFXmCRZj4=\",\"salt\":\"6CWbt59QA3jGeQuozB7RhIvRLHtueOu3wLl5eFmU/cCvezPgW0/VuU+estR8HCkgV8CSfP+KM06Sv+ounMBru3zqeuEqbVU+bnRMqbyxJlpD8D0lsytS29LgGNwRx3/UtB7JKsykyR3d4vRW2+2ZLOlcIoc2lnZ5SJXDh8RVkjY=\",\"iterations\":10000,\"keylen\":128,\"digest\":\"sha512\"}","func":"pbkdf2"} | ||
credential.verify(hash, 'We are all unicorns', (match) =>{ | ||
console.log(match); | ||
//=> true | ||
}) | ||
}); | ||
credential.hash('We are all unicorns', {func: 'pbkdf2'}) | ||
.then(hash) => { | ||
// Hash and verify with pbkdf2 and custom configs | ||
credential.hash('We are all unicorns', {func: 'pbkdf2', digest: 'sha1', iterations: 15000}, (err, hash) => { | ||
console.log(hash); | ||
//=> {"hash":"{\"secret\":\"0SmO6mZB/pGebWX9rBhUDt06hkQ/2yV3Uso6qzyxEdNlXrvo5aX7QuLz9YlQc6iYbKSAO9s2OGi7V0B45TMzkmgQsFK+iFVqkbOlkk8ySyXHVrkISGZoIj9z+VLZ/3jaRCyDzI2dZfoR4IOI3GhYbK/c5jdTPO+YVp2zJHmNHOo=\",\"salt\":\"cxMTjM7yqvIfUoKjjC0nS5DBVXnQllT69DXrS89S2GmzxJrFZ44FCGwbydSQPE7RzzcDUo7C+l3nSh/79LUxWFhQzN7gaFNCKlBvMfSE4qFxU6jyqRTL12/XW1P7FxzE4dPSySXCql5GbryHJSWxofX7GljBKiVd+iYW4cfkUaM=\",\"iterations\":15000,\"keylen\":128,\"digest\":\"sha1\"}","func":"pbkdf2"} | ||
credential.verify(hash, 'We are all unicorns', (match) =>{ | ||
console.log(match); | ||
//=> true | ||
}) | ||
}); | ||
``` | ||
console.log(hash); | ||
//=> {"hash":"{\"secret\":\"fo3R+bNr2guklSeg1FGoWGIpyrDQ03aPeoTxP90zkVWAISZFIO5S0qQTZtmAAyrmzJFEPdDxK6BX3P3jo+MtG+Fvk5qr+Tfrx2QqemQjrJOLN506SxnqvVs1tlm81QteAgZ5/ZCA55Onv5W9f/EkxgSyrCyqcdkKi/KFXmCRZj4=\",\"salt\":\"6CWbt59QA3jGeQuozB7RhIvRLHtueOu3wLl5eFmU/cCvezPgW0/VuU+estR8HCkgV8CSfP+KM06Sv+ounMBru3zqeuEqbVU+bnRMqbyxJlpD8D0lsytS29LgGNwRx3/UtB7JKsykyR3d4vRW2+2ZLOlcIoc2lnZ5SJXDh8RVkjY=\",\"iterations\":10000,\"keylen\":128,\"digest\":\"sha512\"}","func":"pbkdf2"} | ||
## API | ||
credential.verify(hash, 'We are all unicorns') | ||
.then(match) => { | ||
console.log(match); | ||
//=> true | ||
}); | ||
### hash(password, options, callback) | ||
}); | ||
Creates a new 'unique' hash from a password. | ||
// Hash and verify with pbkdf2 and custom configs | ||
credential.hash('We are all unicorns', {func: 'pbkdf2', digest: 'sha1', iterations: 15000}) | ||
.then(hash) => { | ||
#### password | ||
console.log(hash); | ||
//=> {"hash":"{\"secret\":\"0SmO6mZB/pGebWX9rBhUDt06hkQ/2yV3Uso6qzyxEdNlXrvo5aX7QuLz9YlQc6iYbKSAO9s2OGi7V0B45TMzkmgQsFK+iFVqkbOlkk8ySyXHVrkISGZoIj9z+VLZ/3jaRCyDzI2dZfoR4IOI3GhYbK/c5jdTPO+YVp2zJHmNHOo=\",\"salt\":\"cxMTjM7yqvIfUoKjjC0nS5DBVXnQllT69DXrS89S2GmzxJrFZ44FCGwbydSQPE7RzzcDUo7C+l3nSh/79LUxWFhQzN7gaFNCKlBvMfSE4qFxU6jyqRTL12/XW1P7FxzE4dPSySXCql5GbryHJSWxofX7GljBKiVd+iYW4cfkUaM=\",\"iterations\":15000,\"keylen\":128,\"digest\":\"sha1\"}","func":"pbkdf2"} | ||
Type: `string` | ||
credential.verify(hash, 'We are all unicorns') | ||
.then(match) => { | ||
console.log(match); | ||
//=> true | ||
}); | ||
The password to hash. | ||
}); | ||
``` | ||
#### options | ||
Type: `object` | ||
Configurations for the hash function. | ||
##### iterations | ||
Type: `number`<br> | ||
Default: 10000 | ||
The number of `pbkdf2` iterations. | ||
The number of iterations recommended to ensure data safety changes every year as | ||
technology improves. | ||
##### keylen | ||
Type: `number`<br> | ||
Default: 128 | ||
The length of the generated keys. | ||
##### digest | ||
Type: `string`<br> | ||
Default: 'sha512' | ||
The digest algorithm. Available options are: `'sha1'`, `'sha256'`, `'sha512'`. | ||
#### callback(err, hash) | ||
Type: `function` | ||
Called after the hash has been computed. | ||
#### err | ||
Type: `object` | ||
Possible error thrown. | ||
#### hash | ||
Type: `object` | ||
The generated hash. | ||
### verify(hash, input, callback) | ||
Determines whether or not the user's input matches the stored password. | ||
#### hash | ||
Type: `string` | ||
An hash generated from this package. | ||
#### input | ||
Type: `string` | ||
User's input input. | ||
#### callback(err, valid) | ||
Type: `string` | ||
Called after the verification process has been computed. | ||
#### err | ||
Type: `object` | ||
Possible error thrown. | ||
##### valid | ||
Type: `boolean` | ||
True if the hash computed for the input matches. | ||
## Authors | ||
@@ -136,0 +68,0 @@ * **Simone Primarosa** - [simonepri](https://github.com/simonepri) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
5
9491
100
73