Now, core to most (if not all) REST APIs is client authentication. Having spent untold hours on Spring, PHP, and .NET-based web projects, most would agree that bcrypt is considered a best practice for storing passwords in most cases (discussing scrypt and the like is outside of the scope of this article).
(Side note: For an excellent summary on password storage, check out OWASP's cheat sheet here.)
So, using bcrypt in my Node.js applications is a pretty safe bet.
npm install bcrypt
And, in our actual Node.js code...
var bcrypt = require('bcrypt'); // create hashed password (synchronously) var password = bcrypt.hashSync("abc123DEF", 12); // where 12 is the work factor // check passed-in password (sychronously) var isMatchingPassword = bcrypt.compareSync("abc123DEF", password);
So What? This Is All Pretty Obvious
In most cases, this would be sufficient, especially if you plan to deploy to a *nix-based environment; however, as can often be the case, developers may need to develop in a Windows environment. Now, short of a VM or Docker-based solution, this can be a tricky proposition.
This particular bcrypt library requires external libraries such as OpenSSL, VC++ runtimes, and other Windows SDK-based libraries. Older, 32-bit versions of Windows don't seem to have much of a problem; however, with 64-bit versions now becoming the norm, there have been several instances where running the code above in such an environment have been plagued by problems.
Oh. I See. So, What Can I Do?
For some, the solutions listed here in StackOverflow may be enough to overcome the issues and get the bcrypt library above working.
For others, though, this may not be the case. Speaking from experience, I managed to waste half a day going through those solutions in various permutations to no avail. And, for a company that does not have a lot of time to waste on environment setup, I abandoned the task feeling somewhat defeated by Windows (which I am sure happens to many users regularly).
This solution works great! But it isn't without its tradeoffs, namely...
Adrian Lynch has a good benchmarking utility for such a comparison located here. I cloned the repository and modified it to also compare bcrypt-nodejs (the other two libraries mentioned above are already in the code).
Here are some results gathered while running the benchmarks with a work factor of 12, iterating through each version 10 times, run on my Macbook Pro (Intel i5 2.6GHz, dual cores, 16GB RAM):
➜ bcrypt-vs-bcrypt git:(master) ✗ node index.js Bcrypts ready? Fight! bcrypt - 10 iterations took 3304ms which is an average of 330ms each bcrypt-nodejs - 10 iterations took 8554ms which is an average of 855ms each bcryptjs - 10 iterations took 9214ms which is an average of 921ms each twin-bcrypt - 10 iterations took 8978ms which is an average of 897ms each ➜ bcrypt-vs-bcrypt git:(master) ✗ node index.js Bcrypts ready? Fight! bcrypt - 10 iterations took 3290ms which is an average of 329ms each bcrypt-nodejs - 10 iterations took 8350ms which is an average of 835ms each bcryptjs - 10 iterations took 8896ms which is an average of 889ms each twin-bcrypt - 10 iterations took 8990ms which is an average of 899ms each ➜ bcrypt-vs-bcrypt git:(master) ✗ node index.js Bcrypts ready? Fight! bcrypt - 10 iterations took 3268ms which is an average of 326ms each bcrypt-nodejs - 10 iterations took 8244ms which is an average of 824ms each bcryptjs - 10 iterations took 8966ms which is an average of 896ms each twin-bcrypt - 10 iterations took 9140ms which is an average of 914ms each ➜ bcrypt-vs-bcrypt git:(master) ✗ node index.js Bcrypts ready? Fight! bcrypt - 10 iterations took 3309ms which is an average of 330ms each bcrypt-nodejs - 10 iterations took 8270ms which is an average of 827ms each bcryptjs - 10 iterations took 8886ms which is an average of 888ms each twin-bcrypt - 10 iterations took 9097ms which is an average of 909ms each ➜ bcrypt-vs-bcrypt git:(master) ✗ node index.js Bcrypts ready? Fight! bcrypt - 10 iterations took 3321ms which is an average of 332ms each bcrypt-nodejs - 10 iterations took 8306ms which is an average of 830ms each bcryptjs - 10 iterations took 9000ms which is an average of 900ms each twin-bcrypt - 10 iterations took 8973ms which is an average of 897ms each
So, roughly 3 passwords/second can be handled in this comparison at best by the original bcrypt library, with just over 1 password/second being handled by the other libraries. Depending on your throughput requirements and the processor on which you will be running the code, you may have to do some tweaking with the work factor. The degree of security required in your project coupled with your destination server's CPU may mean that the tradeoff of speed is not acceptable.
The bottom line is to be prepared ahead of time and do the benchmarking tests to determine which bcrypt library is going to work best for you in your Node.js application. Usually, however, unless you have a team that includes Windows developers who absolutely must use a native Windows environment, the original, compiled bcrypt library will always be your best.