SALT and HASH password in nodejs w/ crypto
In whatever persistence mechanism (database) you're using, you would store the resulting hash alongside the salt and number of iterations, both of which would be plaintext. If each password uses different salt (which you should do), you must also save that information.
You would then compare the new plain text password, hash that using the same salt (and iterations), then compare the byte sequence with the stored one.
To generate the password (pseudo)
function hashPassword(password) {
var salt = crypto.randomBytes(128).toString('base64');
var iterations = 10000;
var hash = pbkdf2(password, salt, iterations);
return {
salt: salt,
hash: hash,
iterations: iterations
};
}
To validate password (pseudo)
function isPasswordCorrect(savedHash, savedSalt, savedIterations, passwordAttempt) {
return savedHash == pbkdf2(passwordAttempt, savedSalt, savedIterations);
}
Based on the nodejs documentation (http://nodejs.org/api/crypto.html), it doesn't look like there is a specific method that will validate a password for you. To validate it manually, you will need to compute the hash of the currently provided password and compare it to the stored one for equality. Basically, you will do the same thing with the challenge password that you did with the original, but use the salt stored in the database instead of generating a new one, and then compare the two hashes.
If you aren't too committed to using the built in crypto library, I might recommend using bcrypt instead. The two are about equal on the security front, but I think bcrypt has a more user-friendly interface. An example of how to use it (taken directly from the bcrypt docs on the page linked above) would be this:
Create a hash:
var bcrypt = require('bcrypt');
var salt = bcrypt.genSaltSync(10);
var hash = bcrypt.hashSync("B4c0/\/", salt);
// Store hash in your password DB.
To check a password:
// Load hash from your password DB.
bcrypt.compareSync("B4c0/\/", hash); // true
bcrypt.compareSync("not_bacon", hash); // false
Edit to add:
Another advantage of bcrypt is that the output of the genSalt function contains both the hash and the salt in one string. This means that you can store just the single item in your database, instead of two. There is also a method provided that will generate a salt at the same time that the hashing occurs, so you don't have to worry about managing the salt at all.
Edit to update:
In response to the comment from Peter Lyons: you're 100% correct. I had assumed that the bcrypt module that I had recommended was a javascript implementation, and therefor using it asynchronously wouldn't really speed things up on node's single threaded model. It turns out that this is not the case; the bcrypt module uses native c++ code for it's computations and will run faster asynchronously. Peter Lyons is right, you should use the asynchronous version of the method first and only pick the synchronous one when necessary. The asynchronous method might be as slow as the synchronous one, but the synchronous one will always be slow.