In 2013 Forbes reported that approximately 30,000 sites across the globe are hacked each day. Yet, for some odd reason, in 2015, I still see web applications that employ questionable password storing mechanisms e.g. storing passwords in plain text or just hashing them with md5. With 30,000+ sites hacked a day, there is a strong chance that your site will be hacked next.

Why is this a problem?

Let’s assume that your site has been hacked and attacker did somehow get a hold of your database (which is not that difficult, once attacker gets to the web server). So, with database in hand and passwords stored as plain text, attacker can get usernames and passwords for each and every user registered to your site. This means, that the least he can do is log in as them to your site and do nasty things.

On top of that, users are odd sort of people with limited memory capability and as such, they tend to use same username and password combinations on multiple sites (you know, like web mail, Amazon store, Facebook, Twitter etc.). With access to those, attacker can obtain control over entire online persona of your users. Think that is not your problem? When attacker boasts how he obtained information (and trust me, he will do that sooner than later), you can close the shop.

If plain-text passwords are not secure, I can just hash them with md5 algorithm. Right? You couldn’t be more wrong. Hashing is a one way encryption process and as such prevents anyone from obtaining original value once it has been hashed. That is exactly what we want. However, md5 algorithm is the simplest and fastest of them all. Meaning, that with a half decent personal computer, person can easily obtain at least certain common passwords (like Password, 123456 etc.) by using brute force. Also, md5 algorithm has an issue with creating equal hash for different input values, making it additionally insecure.

So, what to do?

As Jeff Attwood wrote back in 2007, storing passwords is not an easy task. Hence, if you can, avoid it. Use OAuth or similar providers and leave the task of storing passwords to big companies like Google, Facebook, Github etc. All you need to do is register your application at provider’s site and use obtained key to process authentication requests.

If you absolutely must use your own solution, the bare minimum is to read OWASP cheet sheat and implement those steps. To sum it up:

  • generate random salt
  • append salt to password (position doesn’t matter as long as it is the same at all times)
  • hash your salt + password using either SHA-256 or SHA-512 algorithm
  • do many iterations of hashing (the last I checked, recommended iteration number was 1000)
  • finally, store salt and obtained hash in your database.

In .NET, Microsoft was kind enough to provide us with RNGCryptoProvider that you can use for salt generation and password hashing.

It is also a good idea to force users into using strong passwords. As much as I agree, that complexity of passwords will just make users write it down in some public place, you are still better off preventing idiot passwords like ‘P@ssw0rd’, ‘Password’, ‘123456’ and similar. Those passwords are well known and no level of encryption will prevent attackers from entering users account and messing about.


More bad news ahead…

You’ve done all you needed. Good for you. Bad news is, it won’t stop there. With the combination of cheaply available processing power and rainbow tables, attackers will be able to crack more and more complex passwords and their hashes. Hence, you need to stay on top of your game and prevent your password storage policy from getting obsolete without anyone noticing. There is hardly a worse publicity than news of your site getting hacked.