The aim of password storage security is to prevent pre-computed hashing reasonably enough. No amount of password hashing even if it takes 1000 years to hash a password if your users use '12345678' as a password.
Salting protects against pre-computed hashes (rainbow tables [0]). Otherwise I can pre-compute many bcrypt hashes and then quickly look up the password.
[0] https://secure.wikimedia.org/wikipedia/en/wiki/Rainbow_table...
All secure password storage schemes are randomized. If you insist on using the word "salt", then just know that bcrypt, scrypt, and the PBKDFs build the salt in. You cannot "pre-compute many bcrypt hashes and quickly look up passwords". So: if you're using a scheme that requires you to think about salts, you are virtually certain to be using an insecure storage scheme.
And, dictionary and brute force attacks are the entire problem bcrypt is designed to address. Go back to that article that you didn't really read, follow the first Usenix link, and read the Usenix paper it cites.
Some functions[0][1] seem to optionally allow the use of salt, are you saying that users should just use passwords as input with bcrypt hashing?
In the article, it does not suggest only bcrypt as well [2].
[0] http://www.mindrot.org/projects/py-bcrypt/
[2] http://www.usenix.org/events/usenix99/provos/provos_html/nod...
The bcrypt libraries that require users to explicitly provide a salt are themselves doing their users a (slight) disservice, by making it seem as if there was a reasonable option for salt generation other than simply using a CSPRNG.
... and this is another reason why people should use one of the bcrypt() implementations for their language* - the API makes doing the wrong thing difficult or impossible.
* disclosure: I ported/wrote a couple of them
Quick quiz: how does HN store passwords? How about apple.com? Facebook? Twitter? Gawker? Sony Pictures? Perlmonks?
A suitably paranoid person would assume any password you've given to somebody else's website is compromised.
Do not reuse passwords ever. Don't even think "I'm just trying this new web service out, I'll use the same password I always use when trying new things out", 'cause you'll end up forgetting to upgrade that password when something gradually changes from "some new and maybe interesting website" to "somewhere that is an important part of my online reputation" or "somewhere I've given authority to charge my credit card".
(and, even more importantly, don't ever fall into that trap when developing server side code "Oh, I'll just do a quick login method for testing that just stores cleartext passwords, I'll fix that bit up before we go live..." Because one day that code _might_ end up live...)
Unsalted SHA1.
(def shash (str)
(let fname (+ "/tmp/shash" (rand-string 10))
(w/outfile f fname (disp str f))
(let res (tostring (system (+ "openssl dgst -sha1 <" fname)))
(do1 (cut res 0 (- (len res) 1))
(rmfile fname)))))
... (and user pw (aand (shash pw) (is it (hpasswords* user))))Instead, all the top 25 passwords found in the recent Sony exposures from here: http://www.troyhunt.com/2011/06/brief-sony-password-analysis... are found in that well known rainbow table, Google...
iains-imac: bigiain$ echo -n 'bailey' | openssl sha1 b1f45ed147d6803ac1a2a91bdea1fab603f910a5
http://www.google.com/search?q=b1f45ed147d6803ac1a2a91bdea1f...
If HN ever gets 0wn3d, anybody with a (password) dictionary word or 8-9 char or less password will almost certainly be exposed. (even if the database doesn't get broken into, anybody who gets enough shell on the webserver to read /tmp/shash will be able to see cleartext passwords passing through...)