Simon Miller Team : Web Development Tags : Web Development

Salted Password Hashing

Simon Miller Team : Web Development Tags : Web Development

I’ve talked before about website security at a high level. There’s many aspects to consider when securing your website (SSL certificates, PCI compliance for payments, XSS protection) however I wanted to touch on the technical aspect of password hashing.

Back in the cowboy days of web development, password security wasn’t well considered. I distinctly remember inheriting projects that stored passwords as plain text in the database. Needless to say this is BAD and you should feel BAD.

Then we moved onto reversible encryption, that is, a basic level of encryption (most likely base64 encoding) that can be reversed to the original stored characters if you know the primer. This is also BAD.

The ideal scenario – and one all good developers have been following for years now – is password hashing. This technique uses the SHA1 cryptographic library available in your favourite programming language (in Microsoft .NET that would be FormsAuthentication.HashPasswordForStoringInConfigFile(password, "SHA1")) to turn plain text into an irreversible, encoded string. How is an irreversible string useful? This user flow explains:

  1. User goes to website and enters their Username (or email address) and Password into the login form. This is behind SSL.
  2. Both credentials are transmitted in plain text to the server but secured under SSL.
  3. Server-side code looks up the user in the database by the Username
  4. If found, the record is retrieved. This will contain the saved password hash.
  5. The Password which was entered on the form is then hashed in memory and – this is the important part – the hash is compared to the hash retrieved from the database
  6. If the hashes match, authenticate the user.

Very simple. However, hashing your passwords is not enough. If my password is “tarantula” and your password is “tarantula”, the two hashes saved in the database will be identical. This will provide any hacker with a clue to your password security. That is where adding a salt benefits.

A salt is another cryptographic string, randomly generated (with .NET you can use System.Security.Cryptography.RNGCryptoServiceProvider), and appended to the plain text password before the hash is applied. This salt is then saved in the database next to the hashed password. This changes step 5 above:

  1. Salt is retrieved from user record and appended to the user’s entered password. The whole string is then hashed in memory and compared to the saved database hash.

By doing the above extra step, two passwords that are the same in plain text will not appear the same in the database. An important side note to this is never reuse salts between records or you are simply defeating the purpose – always randomly generate them and use only once.