Authentication - Part 4.75Fri Nov 16, 2012
Man, I'd better wrap this shit up before my Authentication series becomes Zeno's Article. This particular column won't be contributing to the cause, unfortunately; this is more errata than another installment.
Its been pointed out to me that SHA-2|1| is actually a pretty poor choice of hash function for password storage. The why of it is explained over in this article, which conveniently starts off by recommending
bcrypt and linking you to implementations for a variety of popular languages.
bcrypt looks good for password storage for a number of reasons, including pre-resolved salt, slow hashing speed and an adjustable work factor. Still, read through the entire article, and then look through this one, aggressively titled "Don't Use Bcrypt", which introduces another couple of algorithms which you might want to pick over it for various reasons. As it turns out,
scrypt is also implemented for a variety of languages and provides much poorer performance|2|, while PBKDF2 has been around longer and has therefore seen more battlefield sorties.
I'm not going to recommend one.
They're all better than the
SHA family for this particular purpose, and they all implement salting for you, so any of them will be an improvement if you ended up blindly copying out the code I had previously posted. Thing is, like I mentioned last time, you really should understand the possible attacks in a given situation, and pick a hash that counters them appropriately. I kind of agree with the second guy; yes,
bcrypt is much better than some options, but don't take that to mean "Just use
bcrypt from now on". You need to evaluate your situation and pick a hash function that fits it.
All that having been said,
bcrypt is going to be beat out a
SHA-2 in a known-cyphertext attack. That is, in the situation where your attacker has a copy of your user database, including all the salt and password hashes. In this situation, they can probably brute-force passwords hashed with
SHA-2. The problem is that
SHA-2 is fast, so it's possible to try several hundred thousand per second even with a relatively modest machine, whereas hashing a string with
bcrypt or similar actually takes a second or so. You can't brute force faster than the algorithm produces output, so the slower ones are going have a security advantage there.
All that having been said. You know what would completely sidestep the entire fucking question? Using RSA keys to identify and authenticate your users. You wouldn't need to hash dick because all you'd store is their public key. Because you wouldn't need to hash anything, you wouldn't need to salt anything. Because you wouldn't be using a password, your users wouldn't have to remember any additional information.
Yes, it's currently more work to put together a working RSA-based authentication system, and yes you have to offer it as an option because the general public hasn't caught on to it yet, but it's the Right Way to do auth|3|. Just putting it out there.
1 - |back| - Whichever
SHA-2 you like, it doesn't matter for the purposes of this exercise.
2 - |back| - Slow, as both of those articles note, is actually what we want in a password hashing function. So while that may sound like a dig, it's not.
3 - |back| - At least until cheap-ish quantum computers become available. Hopefully someone works up a better trap-door function before then. Anyway, I get the feeling that it's far enough off that RSA auth would still be worth implementing in the interim.