Authentication Salt And Hash

Authentication is verifying you are who you say you are. Authorisation is letting you do only what you are allowed to do.

HTTP is stateless, that is how it was designed. However I wouldn't like to have to enter a username and password on every page of every website though, that would be sooo tedious. A work around for this is an HttpSession object, which is a unique id for the session (created on the server and stored in either a cookie or a request parameter). This session data is sent back and forth between client and server using HTTP Headers. You can see headers by using curl using the verbose flag.

curl -v http://www.google.com/

Authentication types

  • Session Based
  • Basic Authentication
  • OAuth
  • HMAC

Salt n' Hash

In cryptography, a salt is random data that is used as an additional input to a one-way function that hashes a password or passphrase. The primary function of salts is to defend against dictionary attacks versus a list of password hashes and against pre-computed rainbow table attacks. Wikipedia

Never create your own Hash function, use ones like SHA256, SHA512, RipeMD, and WHIRLPOOL.

Hash algorithms are one way functions. Data goes in, data comes out.

  1. The user creates an account
  2. Their password is hashed and stored in the database. At no point is the plain text (unencrypted) password ever written to the hard drive
  3. When the user attempts to login, the hash of the password they entered is checked against the hash of their real password (retrieved from the database)
  4. If the hashes match, the user is granted access. If not, the user is told they entered invalid login credentials
  5. Steps 3 and 4 repeat every time someone tries to login to their account

I always resented messages like 'Either username or password is incorrect'. However, this ambiguity is in place to prevent hackers validating username or password.

We can randomize the hashes by appending or prepending a random string, called a salt, to the password before hashing. As shown in the example above, this makes the same password hash into a completely different string every time.

A new random salt must be generated each time a user creates an account or changes their password.

To store a password

  1. Generate a long random salt using a CSPRNG.
  2. Prepend the salt to the password and hash it with a standard cryptographic hash function such as SHA256.
  3. Save both the salt and the hash in the user's database record.

To validate a password

  1. Retrieve the user's salt and hash from the database
  2. Prepend the salt to the given password and hash it using the same hash function
  3. Compare the hash of the given password with the hash from the database. If they match, the password is correct. Otherwise, the password is incorrect

Example

const bcrypt = require(bcrypt);

app.post('/login', function(request, response) { const { username, password } = request.body; const salt = bcrypt.genSaltSync(10); const hash = bcrypt.hashSync(password, salt); const userObj = db.users.findOne({ username: username, password: hash });

if(userObj){
    request.session.regenerate(function(){
        request.session.user = userObj.username;
        response.redirect('/restricted');
    });
}
else {
    res.redirect('login');
}

});

References