wildduck/lib/hashes.js

96 lines
2.6 KiB
JavaScript
Raw Normal View History

2018-09-07 15:56:11 +08:00
'use strict';
const bcrypt = require('bcryptjs');
const pbkdf2 = require('@phc/pbkdf2'); // see https://www.npmjs.com/package/@phc/pbkdf2
2018-09-11 20:49:35 +08:00
// this crap is only needed to support legacy users imported from some older system
const cryptMD5 = require('./md5/cryptmd5').cryptMD5;
const consts = require('./consts');
2018-09-07 15:56:11 +08:00
// just pass hashing through to bcrypt
2019-07-11 15:52:43 +08:00
module.exports.asyncHash = async password => {
2019-01-25 21:19:51 +08:00
password = (password || '').toString();
switch (consts.DEFAULT_HASH_ALGO) {
case 'pbkdf2':
2019-07-11 15:52:43 +08:00
return await pbkdf2.hash(password, {
iterations: consts.PDKDF2_ITERATIONS,
saltSize: consts.PDKDF2_SALT_SIZE,
digest: consts.PDKDF2_DIGEST
});
case 'bcrypt':
default:
2019-07-11 15:52:43 +08:00
return await bcrypt.hash(password, consts.BCRYPT_ROUNDS);
}
};
2018-09-07 15:56:11 +08:00
2019-07-11 15:52:43 +08:00
module.exports.hash = (password, callback) => {
module.exports
.asyncHash(password)
.then(hash => callback(null, hash))
.catch(callback);
};
2018-09-07 15:56:11 +08:00
// compare against known hashing algos
2019-07-11 15:52:43 +08:00
module.exports.asyncCompare = async (password, hash) => {
2019-01-25 21:19:51 +08:00
password = (password || '').toString();
hash = (hash || '').toString();
let algo = [].concat(hash.match(/^\$([^$]+)\$/) || [])[1];
algo = (algo || '').toString().toLowerCase();
2019-01-25 21:19:51 +08:00
switch (algo) {
case 'pbkdf2-sha512':
case 'pbkdf2-sha256':
case 'pbkdf2-sha1':
2019-07-11 15:52:43 +08:00
return await pbkdf2.verify(hash, password);
2018-09-07 15:56:11 +08:00
case '2a':
case '2b':
case '2y':
2019-07-11 15:52:43 +08:00
return await bcrypt.compare(password, hash);
2018-09-07 15:56:11 +08:00
case '1': {
let result;
2019-07-11 15:52:43 +08:00
let salt = hash.split('$')[2] || '';
result = cryptMD5(password, salt) === hash;
return result;
2018-09-07 15:56:11 +08:00
}
default:
2019-07-11 15:52:43 +08:00
throw new Error('Invalid algo: ' + JSON.stringify(algo));
2018-09-07 15:56:11 +08:00
}
};
2019-07-11 15:52:43 +08:00
module.exports.compare = (password, hash, callback) => {
module.exports
.asyncCompare(password, hash)
.then(result => callback(null, result))
.catch(callback);
};
module.exports.shouldRehash = hash => {
2019-01-25 21:19:51 +08:00
hash = (hash || '').toString();
let algo = [].concat(hash.match(/^\$([^$]+)\$/) || [])[1];
algo = (algo || '').toString().toLowerCase();
2019-01-25 21:19:51 +08:00
switch (algo) {
case 'pbkdf2-sha512':
case 'pbkdf2-sha256':
case 'pbkdf2-sha1':
return consts.DEFAULT_HASH_ALGO !== 'pbkdf2';
case '2a':
case '2b':
case '2y':
return consts.DEFAULT_HASH_ALGO !== 'bcrypt';
case '1': {
return consts.DEFAULT_HASH_ALGO !== 'md5-crypt';
}
default:
return false;
}
};