How to hash, store and validate a password

How to hash, store and validate a
password

Banner source: https://blog.emsisoft.com/en/29524/how-to-create-manage-store-passwords/

Rule #1: Never ever invent your own crypto algorithm.

What makes a good hashing algorithm?

A good algorithm for hashing passwords:

  • Is deterministic: the same plaintext will always produce the same hash;
  • Produces a completely different result if a single bit of the plaintext is
    changed;
  • Is resistant to collision attacks. Two different plaintexts can sometimes produce the same hash, however, if the method to create this same hash is known, the algorithm shouldn't be used;
  • Is resistant to Rainbow Table attacks by using salts;
  • Is compatible with performance requirements: always check benchmarks;
  • Allows parallelism in order to prevent the server from becoming
    unresponsive
    during hashing;
  • Doesn't have other known vulnerabilities: Google is your friend.

tl;dr use Bcrypt

Coda Hale's How To Safely Store A Password provides an excellent explanation as to why Bcrypt is currently preferred to all the other popular hashing algorithms.

Also, this is the hashing algorithm recommended by OWASP:

Use Bcrypt unless you have a good reason not to.

If you really can't use Bcrypt:

  • remember to always add a salt to your hash in order to prevent rainbow-table attacks (you can even add a pepper);
  • make sure you're using an appropriate number of hashing rounds.

NodeJS Example

If you're developing a NodeJS application, the bcrypt package is a great library to:

  • hash the plaintext passwords you receive from the front-end during the user registration process;
  • compare the plaintext passwords entered by the user during login with the hash previously stored in the DB.

Note: make sure you're using at least 12 rounds.

import bcrypt from 'bcrypt'

const password = 'myv3rys3cr3tp@ssw0rd'
const rounds = 12

bcrypt.hash(password, rounds, (err, hash) => {
    if (err) {
    	console.error(err)
    	return
    }
    console.log(hash)
})

bcrypt.compare(password, hash, (err, res) => {
    if (err) {
        console.error(err)
        return
    }
    console.log(res) //true or false
})

Resources