I am currently using the following for hashing passwords:
var pass_shasum = crypto.createHash(\'sha256\').update(req.body.password).digest(\'hex\');
Bcrypt isn't a bad choice, but there are a few gotchas:
NUL
bytes.As of October 2019, Argon2id is the optimal choice.
The preferred way of interfacing with Argon2id is through libsodium (a cryptography library that provides a lot of features). There are several bindings to choose from, but the easiest is probably sodium-plus.
const SodiumPlus = require('sodium-plus').SodiumPlus;
let sodium;
(async function(){
if (!sodium) sodium = await SodiumPlus.auto(); // Autoload the backend
let password = 'Your example password goes here. Provided by the user.';
// Hashing...
let hash = await sodium.crypto_pwhash_str(
password,
sodium.CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
sodium.CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);
// You can safely store {hash} in a database.
// Checking that a stored hash is still up to snuff...
let stale = await sodium.crypto_pwhash_str_needs_rehash(
hash,
sodium.CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
sodium.CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);
if (stale) {
// Rehash password, update database
}
// Password verification
let valid = await sodium.crypto_pwhash_str_verify(password, hash);
if (valid) {
// Proceed...
}
})();
The documentation for sodium-plus on Github includes password hashing and storage.