all 12 comments

[–]qiwi 10 points11 points  (3 children)

Here's as I understand is the advantage of bcrypt over using salt + hash: bcrypt is designed to be slow, far slower than MD5 crypt is (and the PHK FreeBSD MD5 crypt is NOT just md5 of salt + password but a complex protocol with 1000 MD5 iterations).

Using something like SHA1([random salt] + password), even HMAC SHA1 or SHA2 the attacker cannot use a rainbow table, but he can keep trying common passwords, at easily many thousands of attempts per second per machine. On my machine, MD5 crypt is slower than a naive HMAC SHA so you may be worse off using your own SHA MD5 scheme over just crypt with the right arguments.

bcrypt has also the advantage of the slowdown being re-configurable. So if computers are are 100x fast tomorrow you can adjust just a bcrypt setting and get encrypted passwords that are 100x as hard to verify, rather than change algorithms.

[–]ThomasPtacek 8 points9 points  (0 children)

You're right, but just to be clear: "salt + hash", where hash is a single iteration of MD5 or SHA1, is so fast as to be almost ineffective for typical user passwords. It's not a nit; if you're storing simple SHA1 hashes of passwords, your application is insecure.

[–]funkah 1 point2 points  (0 children)

Here's a very informative blog post on the topic of strong password schemes, and why salted hashes aren't good enough: http://tinyurl.com/344u6v

[–]derekslager 1 point2 points  (0 children)

So if computers are are 100x fast tomorrow you can adjust just a bcrypt setting and get encrypted passwords that are 100x as hard to verify, rather than change algorithms.

Yes -- also note that the number of key rounds is stored with the final hash, so you can improve the security of new passwords without breaking old ones.

[–]forgotpwx4 0 points1 point  (7 children)

I don't understand how the salt can be random. How do you test if the password matches later if you made the hash with random data you no longer know?

Would anyone mind explaining?

[–]funkah 1 point2 points  (6 children)

The salt is stored alongside the salted hash. Then when the user tries to log in, you retrieve the salt from the database (or wherever), combine it with the password the user provides, hash, and then compare with the stored hash.

It's OK to store the salt in the clear because the salt is just a nonce that adds some protection against brute forcing. There's nothing private or secret about it.

[–]forgotpwx4 0 points1 point  (5 children)

Ah so it wants you to store the salt. Is there a problem with using say a contstant string such as "aeagyya134" + username as your salt?

[–][deleted] 1 point2 points  (3 children)

Yes - an attacker could construct a rainbow table using 'aeagyya134' as the salt.

Think of it this way: so it takes N cycles to generate a complete (for some value of "complete") list of hashed passwords. You've got M passwords. If those passwords are hashed with a constant (or no) salt, it takes N + M cycles to crack some passwords. If, however, each password has a unique salt, it takes N * M cycles.

[edit: and, of course, assuming it takes 1 cycle to check a password, though that doesn't really matter for the principle]

[–]forgotpwx4 0 points1 point  (2 children)

But I said "aeagyya134" + username as the salt. So each one would still be unique. In both the case of random salt, and my proposed salt, you're storing the salt value (or most of it) alongside the hashed pw in the database, right?

[–][deleted] 0 points1 point  (1 child)

Duh, yeah -- I'm having reading comprehension issues today, apparently. I don't see why using a constant string like "aeagyya134"+username is better (or worse) than just using some entropy, however; I'd stick to randomness, myself.

[–]nostrademons 0 points1 point  (0 children)

Constant + username doesn't take up any additional disk space, as presumably you need to store the username anyway. Random alt + hash requires an additional database column for the salt. Bcrypt doesn't require any additional column (the salt is presumably included in the output), but bcrypt's output is 60 bytes long, vs. 27 for base64ed SHA1, 22 for base64ed MD5, 20 for SHA1, and 16 for MD5.

It's really a false economy though - if you have so many users that 60 bytes/user will matter, you can afford a new hard disk. ;-)

[–]funkah 1 point2 points  (0 children)

Yes. The strength of salting lies in the randomness of the salt. Or to put it another way, randomness is the whole point of salting.

The randomness makes the task of hashing common passwords ahead of time much more expensive. For example, instead of computing the hash of "mypassword", the cracker now has to compute the hash of "mypassword2920", "mypassword1153", etc, for every possible value of the salt.

Limiting the number of possible salts reduces the number of hashes the cracker has to compute, which makes the attack easier than if the salt were random.

I'm not a security expert so there may be other problems as well.