dcodeIO / bcrypt.js

Optimized bcrypt in plain JavaScript with zero dependencies.
Other
3.51k stars 267 forks source link

Question: Why a lower limit of 4 on salt rounds? #69

Closed anshul-kai closed 7 years ago

anshul-kai commented 7 years ago

I'm wondering why saltRounds can't be set to anything below 4? Or in other words, when set to less than 4, it would default to 4. Is this just to ensure a strong encryption or is there more to this than that?

dcodeIO commented 7 years ago

I believe this is a historical limit inherited from other libraries. It hasn't to do with the salt, though (did you mean logRounds?), but determines the number of rounds the algorithm is executed through rounds = 2^logRounds. Increasing the parameter by 1 doubles the amount of work required. If n is 4, that'd be just 16 rounds, which is pretty much nothing (note that slightly larger values are pretty much nothing as well today).

See also:

A good answer to the question of how many rounds are ok is to answer a question - how many rounds can you afford without degrading performance?

anshul-kai commented 7 years ago

Thanks for the quick response @dcodeIO. I'm running this on a slow mobile device and the compute time often exceeds 50ms with the lower limit of 50ms. I'm using bcrypt to add a request signature and this starts getting quite expensive when making multiple requests at the same time.

I'm wondering if you'd be willing to accept a PR which allows a user to set the lower and higher limits or perhaps expose these limits on the prototype so that they can be easily overwritten?

Ruffio commented 7 years ago

@dcodeIO what do you say to the question about PR? Is that relevant?

dcodeIO commented 7 years ago

Considering that this library is meant to be compatible to the native bcrypt binding, which has such a limit as well, and that generating a signature is not really what bcrypt is about, I'd rather leave it as is.

Ruffio commented 7 years ago

Then I guess that this 'issue' should be closed. Also it was a question after all...

sripberger commented 5 years ago

I fully understand and agree with the reasoning discussed here, but also I have an annoying use case where I need to relax this lower limit for verifying against a hash.

I have some old password hashes that were created with another library in Python 2.7, which had no such limitation. The dev who created these hashes (perhaps unwisely, though perhaps they had good reason at the time) only chose a cost of 1, leading to only 2 rounds. Since this is bcrypt, there is of course no way for me to strengthen these hashes without the original password.

Short of forcing all users to reset their passwords completely, the only way to deal with this as far as I know is to check against the old 1-cost hash then generate and store the new, higher-cost hash on login.

It would be nice to be able to handle this without forking. I'm thinking I might like to add an optional param to the compare and compareSync methods that would bypass the limit. This would preserve the limit in most use cases, only relaxing it when the developer explicitly wants to.

Would you be open to this possibilty?