5 ms·
bcrypt is only strong if their cost / work-factor is set correctly
by omgitstom 12y ago
bcrypt is only strong if their cost / work-factor is set correctly
- StavrosK 12y agoExactly this. If they used ten rounds, it's dire, and just saying "bcrypt" doesn't say much unless you also specify the number of rounds.
- VBprogrammer 12y agoIt says a lot more than your passwords are safely stored behind unsalted MD5 :)
- tedunangst 12y ago10 rounds of bcrypt is "dire"?
- StavrosK 12y agoYes? 16 rounds take 1ms on my (old) machine. In Python, no less.
- bhauer 12y agoI hate to suggest that your observation is wrong, but 16 rounds should take orders of magnitude more time than 1ms. 16 rounds using Mindrot's Java implementation of BCrypt on my admittedly old 2009-vintage i7 consumes 6.3 seconds to hash a 10-character password.
- StavrosK 12y agoThat's because you're conflating "rounds" with "work factor". "Work factor" is actually 2^rounds, you're using 65536 rounds. Try 4.
- bhauer 12y agoThank you for pointing that out. I suspect many of us in this thread are referring simply to the single parameter to BCrypt.gensalt as the "work factor" or "number of rounds" interchangeably. And you're right, the work factor is what is actually provided to gensalt. Nevertheless, in all implementations I am aware of, the default for that parameter is 10. And earlier, you wrote: > If they used ten rounds, it's dire, and just saying "bcrypt" doesn't say much unless you also specify the number of rounds. tedunangst and I both assumed you were referring to the default 10 work factor of BCrypt and were calling it "rounds" as many of us are doing. The obvious question that tedunangst is asking (and others in this thread) is whether a work factor of 10 is considered too low.
- StavrosK 12y agoNo, a work factor of 10 is usually fine. I generally use PBKDF2, which uses a parameter for actual rounds, and set that to about 20k, but don't think about rounds, just see how many authentications per second you need to be doing at the most, time your servers and use a parameter that gets you those authentications. 200ms is usually okay for most applications.
- tedunangst 12y ago10 is obviously the log rounds number. It's not even a power of two! Nor has any implementation of bcrypt even supported such a low number.
- StavrosK 12y agoHow is it "obvious" when the unit is rounds? Ten was an example, round to 16 if you like. The point is still the same, using few rounds is a risk.
- tedunangst 12y agoBecause the set of values that make sense as linear round counts doesn't overlap with the set that makes sense as log base two work factors. Every implementation takes the log number; it's the only number people ever discuss.
- StavrosK 12y agoAnd do they call it "rounds"? I've only heard it called work factor.
- tedunangst 12y agoAs a shorthand for work factor? Sure. It may be technically inaccurate, much like talking about centrifugal force, but you'll see "10 rounds" far more frequently than you'll see "1024 rounds". There's another thread on this post that refers to it as rounds as well.
- rudolf0 12y agoThe default cost for most libraries and languages is between 10 and 12, which is considered too low for 2015 but still pretty good. As long as they're at the default or above it, I wouldn't be too concerned about an attack against the whole DB. Targeted cracking attempts against specific hashes are definitely still an issue though.
- xrstf 12y agoIf I set bcrypt cost to 11, hashing takes 0.1 seconds. At 12, it takes 1 second roughly. Setting it to anything higher leaves my service open to Denial-of-Service attacks, so I'm very hesitant to increase the cost factor. To you have a credible source for the "10..12 is too low for 2015" claim? HHVM 3.6 on a small Ubuntu server
- jxcl 12y agoYou have either a very slow server or a very bad bcrypt implementation. Running bcrypt in python on my 5 year old server has these results: >>> timeit.timeit("bcrypt.hashpw('this is a password', bcrypt.gensalt(11))", setup="import bcrypt", number=5) / 5 0.13497538566589357 >>> timeit.timeit("bcrypt.hashpw('this is a password', bcrypt.gensalt(12))", setup="import bcrypt", number=5) / 5 0.28287739753723146 >>> timeit.timeit("bcrypt.hashpw('this is a password', bcrypt.gensalt(13))", setup="import bcrypt", number=5) / 5 0.5341608047485351 >>> timeit.timeit("bcrypt.hashpw('this is a password', bcrypt.gensalt(14))", setup="import bcrypt", number=5) / 5 1.069920015335083 >>> timeit.timeit("bcrypt.hashpw('this is a password', bcrypt.gensalt(15))", setup="import bcrypt", number=5) / 5 2.151028203964233 That's five repetitions of a bcrypt hash with the work factor passed in bcrypt.gensalt(). The resulting units are seconds.
- xrstf 12y agoYou are right, my times are apparently somewhat dated. HHVM 3.6 actually gives me 1.88 seconds with costs of 15. Good thing you made me re-measure :) That makes 13 my new bcrypt default.
- tedunangst 12y ago