Hello, I just tried out your module the other day and I noticed that it added roughly 105-110 millisecond load times to my node/express http responses.
Without bcrypt loaded my POST responses happen in about 3-5 milliseconds.
With bcrypt loaded and a 1-5[ish] genSaltSync(rounds) value the same requests happen in about the same time, at most we're losing like 5 milliseconds. Doing a sha-256 with the native crypto module is probably around the same numbers.
I didn't go crazy with testing however when I jump from 5 to 10 rounds it's certainly adding a consistent 100-110 milliseconds to my POSTs (I'm creating a random password).
I do know that bcrypt's nature is to do slow hashing to make it more secure, but is it normal for the curve of slowness to be so non-linear? Any chance the module could use some tweaking to increase the performance? Is using 5 rounds good enough?
Is there a reason you are using it for (what sounds like) every request? bcrypt is not meant to be fast or replace using sha or md5 when you just wnat a simple hash; it is for hashing passwords or other such data where you don't want brute force attacks to be fast.
It's only being ran on the POST request (when a user fills out a form). I believe it must be ran on every POST request because the flow goes something like this:
I was under the impression bcrypt was a more secure version of a standard 256 sha and should be used to replace it to offer a more secure hash? I'm not storing super sensitive data but I might as well protect my users in the best way I can?
I just wonder if 5 rounds is enough because (just guessing here), I'm fairly certain the performance would equal sha-256.
Don't make guesses about security ;)
Are you creating a session for the user once they login or requiring the password for every request (seems wrong). If you just have a login page and then make a session, you only hash on login (typical way to do it).
Hmm, maybe I need to explain this in another way.
---bcrypt is NOT loaded yet---
User loads a sign up page where they fill out their e-mail address and some other non-relevant fields.
User clicks the submit button.
---bcrypt is loaded NOW---
bcrypt generates a salt
bcrypt generates a hashed password
Server logic decides if it wants to accept the input from the user and it either sends a pass or fail result (validation).
Did it pass? Cool, write everything to a persistent data store.
Uh oh, it failed? Send the User back to the form and this loop repeats until it passes or they leave.
[Note: I'm aware I could bcrypt their input only IF my validation passes but ignore that for a moment, it will be like that eventually :). Also it still wouldn't change the problem much.]
Now if a user logs in successfully, yes a session is made and I'm only hashing once. However let's say down the line I want to make my own API and it requires authorization per-request. It WOULD be hashing now on every request, right?
Ok, so where is the problem? Bcrypt is meant to be slower than sha or md5 by nature. Personally, I wouldn't worry about any of this early on, especially given it is a one time login form.
The problem is more of a potential problem / question. I'm aware it's meant to be slower than sha or md5, but I was curious if it was meant to be THAT much slower. 100ms+ is a pretty big deal, especially if you start adding in a non-trivial amount of users. My other question was more of a bcrypt question, if 5 rounds were enough? The performance is completely acceptable with 5.
Oh and if anyone else wants to bench performance, I actually looked at the c++ a bit and realized that there's a hard coded limit range on the number of rounds. The min value is 4 and the max is 31. I guess this explains why 5 rounds is nearly identical to 1 (in reality 1 === 4).
Source:
https://github.com/ncb000gt/node.bcrypt.js/blob/master/src/bcrypt.cc#L142
For bcrypt to be effective, it needs to be THAT much slower, since it's designed to raise the cost of password cracking. At 100ms, that means at least 10 passwords per second or faster for the attacker per machine; at that rate, a single machine w/o optimizations (GPU, etc.) can crack a 6-character non-complex password in an average time of 6 months. Realistically, at 100x speed, that means a 7-character password will fall in 45 days.
Also, the number of rounds is actually 2^x, so it does scale exponentially (by design).
See:
http://en.wikipedia.org/wiki/Bcrypt
http://transvasive.com/index.php?option=com_content&view=article&id=63
Most helpful comment
For bcrypt to be effective, it needs to be THAT much slower, since it's designed to raise the cost of password cracking. At 100ms, that means at least 10 passwords per second or faster for the attacker per machine; at that rate, a single machine w/o optimizations (GPU, etc.) can crack a 6-character non-complex password in an average time of 6 months. Realistically, at 100x speed, that means a 7-character password will fall in 45 days.
Also, the number of rounds is actually 2^x, so it does scale exponentially (by design).
See:
http://en.wikipedia.org/wiki/Bcrypt
http://transvasive.com/index.php?option=com_content&view=article&id=63