Store passwords the right way in your application

Published: 2013-06-11
Last Updated: 2013-06-11 21:59:10 UTC
by Swa Frantzen (Version: 1)
14 comment(s)
I suspect most of our readers know this, but it can't hurt to repeat this every so often as there is a lot of confusion on the issue. One thing that gets to me is seeing reports of website compromises that claim "the passwords were hashed with SHA-256". Well at face value that means 90% of the passwords were decoded before the news hit.
If you have an application that's protected by passwords, there are a few rules to follow:
Rule #1: Never store plain passwords, use a hash
The worst case solution is that passwords are stored as is. Any attacker breaking in to the application now has everything they need to impersonate any user in your application. But typically they have much more: your users typically reuse passwords, so there's no telling to how far this goes. And if the application is e.g. a webmail solution: well all accounts that can be reset by sending an email here are now essentially broken as well.
A hash function is a one-way function: it converts input to output but there is no easy way to reverse the process. There's a whole bunch of algorithms commonly used.
The goal/advantage here is that even if the attacker takes away the user tables, he's still got some work to do. 
Unfortunately the work is doable so we need more ...
Rule #2: Use a salt
Attackers can pre-compute (or buy) so called rainbow tables: it's a list of pre-computed password -> hash values and as such decoding any common password is as fast as a lookup to them gets.
A salt is essentially a random string chosen at the time of password change or creation and stored along with the hash and concatenated to the password. This makes rainbow tables useless.
But it's still not enough...
Rule #3: Use a slow hash function
This rule is most often forgotten, yet it is so critical. 
The most common hash functions we use daily (e.g. SHA-256) are designed to be fast. But for storing passwords that's going to work against us big time.
Even the attacker can't break SHA-512 in a brute force fashion, even if they can't use rainbow tables due to salts being used, they still will find the vast majority of the passwords our users can remember in a manner of minutes to hours if you use a fast hash.
So you need to use a slow hash function.
Since there's a Rule #0 in all things crypto: Don't invent your own: Just use the appropriate functions already there. Many of these slow hash functions allow one to chose the cost. If so, set it as high as you can bear with your current hardware.
In PHP one can use the crypt function using blowfish or many thousands of rounds of SHA-256 or SHA-512 instead of a simple hash function.
Or even better if the cryptographic password hashing extension is installed, use it as it has simple support for e.g. rehashing passwords to update the strength of a hash of a stored password upon login of the user.
Feel free to add comments on how to do it in other languages.

Swa Frantzen -- Section 66

Keywords: hash password
14 comment(s)
Diary Archives