Adding long salts on the other hand requires the attacker to create an infeasible number of rainbow tables (one for each possible value of the salt).
So e.g. computing a rainbow table for all possible Windows 2000 passwords (up to 14 characters but you're actually only doing 56-bit inputs) in the LANMAN scheme took ages, and produced a fairly large file, but having done so that's it, you, or anyone you give the file to, can reverse LANMAN hashes into working passwords almost instantly.
(Microsoft's LANMAN hash lacked salt, and is stupid in various other ways, MD5 would actually have been a better choice than LANMAN, because you allow arbitrary input passwords and thus good passwords are stronger instead of impossible even though MD5 is much too fast for a good password hash)
And bcrypt includes stores a unique salt next to the hash for every password, making rainbow tables completely useless.
EDIT: I mean, I understand maybe why in 2006 you used md5 without salt. But a few years ago I when I tossed together my first webapp (a scheduling system for the community I'm involved in), I just googled "password hash" and immediately bcrypt came up as a recommendation; there was a package in my target programming language, so after half an hour of research and 5 minutes of programming I was done. I don't understand how the opensubtitles team, after having had their password database compromised, came up with "use sha256 without salt" instead of "use bcrypt or one of the many libraries which takes care of all of that for you".
You note that when you googled "Password hash" you got pointed to a decent password hash. But, knowing what questions to ask is half the battle. Too many people figured hey, I should use a cryptographic hash and got pointed to MD5 (or SHA1 or even SHA256) because that's what those are.
The words you should have googled weren't "password hash" but maybe "web authentication" and then the answer is clearly you shouldn't use passwords or any sort of shared secret.
You can have a copy of the authentication database for the toys system I maintain, but it wouldn't help you sign into it because all the information in it is public, a trick we've known how to do in principle for decades, and which works today, on the public Web, with readily available devices (e.g. my phone) and yet, here we are on Hacker News discussing which password hash is best like it's still 1985.
I'm pretty sure it wasn't anywhere near ready to use five years ago when I wrote v1 of my webapp. And googling again, it's still not clear whether it would work on whatever random software setup some of my zealous-for-software-freedom colleagues use. With passwords I don't need to worry: if they can render the HTML+CSS (even the JS is optional, because some of my colleagues prefer NoScript), they can log in.
[1] https://hackaday.com/2012/12/06/25-gpus-brute-force-348-bill...
Yeah, you could rebuild a rainbow table yourself u til you find the collision, but you have to search every bit of the potential hash space.
While bcrypt is already much, much better than using MD5 or SHA256, the best practice is to use Argon2.
In practice, it is more important to use a hashing algorithm that is designed for passwords (e.g. bcrypt, argon2, scrypt) than it is to choose the best one. As this breach shows, many sites are still using insecure hashes, like MD5, because it worked 15 years ago.
I haven't had to write any password storage code since before Argon2 won the 2015 competition so I haven't gone deep on the "side channel attack vs. memory hardness" tradeoff question when picking the mode. I am curious which mode others are using.
The specific modes are useful dependent on the threat model you are protecting against. Argon2i protects better against timing/side-channel attacks and Argon2d protects better against brute-forcing attacks.
In my opinion, a developer should (in most cases) focus on application security instead of picking the perfect hashing algorithm, as application security is far more crucial.
What I mean is, the stored data contains which algorithms it is. So they can in their code or configuration change which algorithms to use and how many times it should hash. Then on login they can verify the password against the hash and also check if the stored hash needs to be rehashed against the current set settings, then it can create a new hash from the password the user entered on login and store that in the database.
Then you get automatic hash upgrades to match the current settings of the hashing of the passwords on the site with basically no user interaction (other than the act of logging in to have the password in plain text).
There are lots and lots of options. Seems like they are a php shop, so even moving to any of these open source PHP server libraries[0] would have been a better move.
Disclosure: I work for a third party auth provider, FusionAuth.
Wait, what? Definitely lesson not learned:
- sha256 is not the proper way to store passwords, it's still vulnerable to the same attack as md5, rainbow tables, because it's a FAST algorithm (sure md5 is also poor for collisions, meaning it's worse, but practical attacks for lists of hashed passwords are rainbow tables). At least with salt+pepper it limits attack surface, but instead you should be hashing your passwords with:
- `password_hash`[1] should be used instead of `hash_hmac`, with the algorithm being "PASSWORD_BCRYPT" or better[2]. This is a slow hashing method, meaning anyone trying to rainbow-table attack your passwords will have a hard time.
- A common technique is not to delete old passwords, but instead to rehash them with the new algorithm. This would be useful for moving from sha256 => bcrypt, since collisions on sha256 are not practical, but if the original hash was md5 then I think it's fine to delete the md5 passwords and require a new one. Good luck to those who changed their email in 15 years though.
[1] https://www.php.net/manual/en/function.password-hash.php
[2] I haven't followed the space too closely for 3-4 years, I'm not sure if bcrypt/blowfish is still the recommended algorithm or there's newer better ones