Closed ThePesta closed 6 years ago
The linked issue also states that computation is split into chunks to make parralelization more efficient. So far I have not had or been made aware of anybody running into actual performance issues around password hashing.
Additionally this is also a security consideration:
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
You can also always customize this to your needs by implementing a custom verifier.
I've made a repo to test the response times of bcryptjs
versus bcrypt
Two tests were ran: 1) Max concurrent user creation requests before the default timeout of 5 seconds was reached 2) Sustained number of user creation requests over 30 seconds
- | Bcryptjs | Bcrypt (1 core) | Bcrypt (2 core) | Bcrypt (4 core) |
---|---|---|---|---|
Max signups | 7 | 10 | 20 | 35 |
Avg time (ms) | 4527 | 3967 | 2934 | 2737 |
Min time (ms) | 4524 | 1971 | 951 | 658 |
Max time (ms) | 4531 | 4783 | 4834 | 4878 |
The simultaneous test scenario where # requests are fired simultaneously show that the maximum number of simultaneous signups with bcryptjs
is 7 on a local machine with a best case scenario not accounting for network latency or additional code execution time from other hooks/operations on the server. With the chunking technique used in bcryptjs
each request has to wait for the other requests.
Utilizing the bcrypt
running on just one core we increase this to 10, as well as not blocking the first requests to receive their response as indicated by the min times. Multi core scaling is an easy benefit as well.
Sustained # of requests per second over 30 seconds was also measured (with the default timeout of 5 seconds):
With bcryptjs
, only one request per second can be sustained infinitely, with two already having issues five seconds in.
With bcrypt
running on one core a max of two requests per second can be sustained infinitely, with a less sharp increase in response times when running three or more requests per second.
With bcrypt
on two cores, a max of four requests per second can be sustained infinitely.
With bcryptjs
on four cores, a max of seven requests per second can be sustained infinitely
Running bcryptjs
versus bcrypt
with one core already shows a doubling in performance, with large gains in going to two cores
Are these performance numbers with bcryptjs
acceptable? As these results only show local response times before network latency is added. If they aren't I'd like to propose a switch to bcrypt
, however I am unsure if the dependencies on C/C++ of bcrypt
has an impact to existing projects.
Thank you for the detailed benchmark. Local authentication used to use bcrypt
but it was causing many compilation issues on different systems (especially Windows of course) so it was changed to bcryptjs
and making things flexible enough to change the password hashing to whatever you need.
The
bcryptjs
library used for creating hashes and comparing password async implementation is known to use the main thread. This causes the rest of a feathers application to be unable to perform other operations and handle new requests.How do you handle multiple concurrent user sign ups and logins when the main thread is busy with the hash generating/password checking?