|I was tempted to reference that Angelina Jolie movie here... But I resisted.|
I won't go over this in too much detail, because that's already been done by many a development blog, but the basics are:
- Never store plain text passwords, store hashes. Storing plain text passwords is a cardinal sin, when a hacker gets ahold of this (assume the worst), they'll have a list of emails and favorite passwords. This is gold to them. They'll get into gmail accounts, and from there it's all over.
- Require some level of complexity to your passwords. Weak passwords are easier to brute force... duh. Enforce a policy that ensures a high level of entropy.
- Salt your passwords prior to hashing. Add something special to each password so it's harder to figure out what it was based off of the hash. A good size salt will also eliminate the effectiveness of rainbow tables.
- ...With a random salt. Even better, everyone gets their own salt. Salt for everybody!
- Make it slow on purpose. This one might seem odd to some people. It's a really good idea to make sure your hashing algorithm is good and slow. This is because if it's too quick it makes it easier to brute force.
Something to know: This security needs to be updated as hardware gets faster. Basically has hardware gets faster, you might want to add iterations to your PBKDF2 step. This is because you'll want to keep the time to compute the hash high enough it's not easily brute forced by current hardware. 200-400 ms on top notch hardware should be more than enough to slow down a brute force attack to the point where it's not feasible.
Microsoft .NET has a built-in implementation of PBKDF2 for iterative stretched key generation and HMAC SHA512 for keyed hash creation. The following code demonstrates such an implementation. I think it's pretty self explanatory, but if not here's the play by play:
- Get a salt using RNGCryptoServiceProvider. This is just a cryptographically secure random number generator.
- Use PBKDF2 (Rfc2898DerivedBytes) to get a key from the salt and the text over many iterations.
- Hash the text with HMACSHA512 using the key and the salt.