EDIT: As noted in the comments, the way I put this originally was kind of flip and misleading and I apologize for creating confusion. My point was that I've seen a number of places do it that way, so just throwing at at your problems doesn't necessarily fix everything.
The right way to prevent a rainbow table attack is to computationally prevent it via unique salts.
But anyhow, I was talking about increasing the security of an already-existing hash algorithm. Even if the recursive hashing isn't that much more secure, it definitely isn't less secure than one pass...
Reverse engineering a novel hash function, while theoretically possible, isn't a capability possessed by the folks dumping passwords from LinkedIn or Riot. And even if it were, doing so would cost more than would be gained by compromising those passwords[2].
Thus, in practical terms, a novel hash function is a great way to undermine attackers, not unlike using Linux or opening files in non-standard viewers (LibreOffice, Nitro PDF Reader, etc.).
1. And if you have access to a good cryptographer, you should absolutely roll a novel hash function as well. Security through obscurity is the proverbial cherry on top of your defensive sundae, i.e. it's only a bad thing if you rely on it exclusively.
2. Not to mention that the whole point of rainbow tables is that they've already been computed. If an attacker has to reverse engineer a hash function to create a rainbow table, that largely defeats the rainbow table's purpose.
2. This is exactly what happened with the custom proprietary "obscure" GSM A5/1 encryption algorithm. First it was reverse engineered (based on a leak), then David Hulton and Steve Muller created rainbow tables for it. The fact that it was a custom algo did not defeat the rainbow table's purpose.
There are many ways a custom hash algo designed by a company could end up being used across multiple of its password databases, and could subsequently be leaked, making the generation of rainbow tables possible and valuable (by rogue employees or hackers), that relying on the obscurity of a custom algo is a bad idea. As you recognized, salting is the ultimate protection. So there is no point in talking about alternatives.
I'm not sure I understand this point, what is the criteria for a function to be novel?
This function produces different hashes from most other hash functions, eg, it is new and possibly novel, but is equivalent to using a single salt across a database:
function novelHash(password) {
return md5("novelHash" + password);
}Moral of the story is to use a unique salt per account, but don't roll your own crypto in the process.
So if I have access to that salt, I generate a new rainbow table and get a huge percent of your users.
The point of salting is to make rainbow tables no more efficient than brute forcing. If each user has a unique salt, there's literally no benefit to generating a rainbow table.
salty = md5(md5(pw) . pw . 'poniesaremagical' . md5(username));?
It is per-user... how is it different than using a timestamp which will be as unique as username?
H(H(Password) + Salt)
If I steal your db and have another db that contains your user's unsalted password hashed with the same hash function, I can easily test if the same password is used in both places, simply by replacing H(Password) with the other hash. This leaks information and provides incentive to continue trying to crack the easiest target, if I really want what you have.A simple change makes this comparison impossible:
salty = H(H(Password + Salt)
Now there's no place to plug in the other hash, so I can't tell if the accounts share passwords until I successfully crack one and try it on the other. I might not bother and focus on lower hanging fruit.Always assume your salting method is public, even if you make attempts to keep it secret. And remember that your site isn't in isolation; your user and every site they interact with are also potentially weak links in the chain.
Note that the examples above are oversimplified. You should look to a better authority on how to properly store passwords. In a future leak, we'll be surprised that the sites involved only salted their passwords.
Site-wide salting has almost the same security as per-user salt, as long as the salt is not leaked or cracked before the database is leaked for pre-computation.
Jesus, no. It absolutely does make it more efficient than brute forcing each password.
I compute one rainbow table that I can run against 10,000 users. Or I brute force 10,000 users' passwords because they have unique salts.
>_< God, I need to just accept the fact that people are going to talk out their ass about this and stop trying to get people to spread bad, insecure information.
oh sweet jesus of irony, you're the guy that was wrapped up in Bitcoinica.
Don't worry, I use per-user salts for all my web projects following all security best practices that I know.