Bcrypt vs BcryptJS: Understanding the Differences and Choosing the Right Encryption Library

As technology evolves, the security of our web applications and user passwords becomes increasingly critical. Ever-evolving technology has produced faster GPUs and CPUs which can perform brute force attacks and easily guess hashed passwords. This is where Bcrypt hashing function offers us a truly robust solution.

Bcrypt is one of the most popularly used password-hashing functions based on the Blowfish block cypher cryptomathic algorithm. Taking the form of an adaptive function, Bcrypt was built to slow down brute-force attacks. Salts are included in the hashing process which can influence the hash output thereby protecting the password hashes against rainbow table attacks.

Bcrypt has its implementation in many programming languages such as C/C++, JavaScript, Go, Ruby, Python, etc. In this article, we’ll be comparing two such implementations for NodeJS applications, the Bcrypt and BcryptJS libraries.

Note: Bcrypt-NodeJS library has been deprecated and BcryptJS is the successor to it.

Learn about JWT authentication in NodeJS here and the basics of password hashing here.

Difference between Bcrypt and BcryptJS library

Even though both libraries implement the same algorithm under the hood, they use different approaches to achieve their result and have different use cases.

Implementation and Source Code Difference

Bcrypt

Bcrypt library is the native C++ binding of the Bcrypt and Blowfish algorithms. The Bcrypt library is a native addon to NodeJS with over 1700000 weekly downloads. This native addon written in C++ is precompiled to a Dynamic Linked Library containing the compiled code and exposes APIs to interact with the compiled code.

BcryptJS

BcryptJS is the implementation of the Bcrypt algorithm in plain JavaScript having similar weekly downloads as the native Bcrypt library. The BcryptJS library doesn’t need any precompilation and works with almost 0 native dependencies and is also compatible with the C++ binding of Bcrypt.

Performance Difference

Performance is one of the major differences both these libraries. We will be taking a look at the performance of these two libraries with practical implementation.

We will be testing both libraries on the basis of their four basic features/APIs:

  1. Synchronous generation of password hash
  2. Synchronous comparison of password hash
  3. Asynchronous generation of password hash
  4. Asynchronous comparison of password hash

We create a new folder and run the following commands in terminal/PowerShell to create a boilerplate to test the performance of these two libraries.

npm init -y
npm install bcrypt bcryptjs

Create an index.js file in the folder which will help us get to run our test script.

Bcrypt

Script:

const bcrypt = require("bcrypt");
const salt = 10;
const password = "someStrongPASSWORD";
let hashAsync;
let hashSync;

console.time("Bcrypt Synchronous Hash Generate");
hashSync = bcrypt.hashSync(password, salt);
console.timeEnd("Bcrypt Synchronous Hash Generate")
console.time("Bcrypt Synchronous Hash Compare");
bcrypt.compareSync(password, hashSync);
console.timeEnd("Bcrypt Synchronous Hash Compare");

console.time("Bcrypt Asynchronous Hash Generate");
bcrypt.hash(password, salt).then((hash) => {
  hashAsync = hash;
  console.timeEnd("Bcrypt Asynchronous Hash Generate");
  console.time("Bcrypt Asynchronous Hash Compare");
  bcrypt.compare(password, hashAsync).then(() => {
    console.timeEnd("Bcrypt Asynchronous Hash Compare");
  });
});

Run the Script:

node index.js

Output:

Bcrypt Performance Output

BcryptJS

Script:

const bcryptjs = require("bcryptjs");
const salt = 10;
const password = "someStrongPASSWORD";
let hashAsync;
let hashSync;

console.time("BcryptJS Synchronous Hash Generate");
hashSync = bcryptjs.hashSync(password, salt);
console.timeEnd("BcryptJS Synchronous Hash Generate")
console.time("BcryptJS Synchronous Hash Compare");
bcryptjs.compareSync(password, hashSync);
console.timeEnd("BcryptJS Synchronous Hash Compare");

console.time("BcryptJS Asynchronous Hash Generate");
bcryptjs.hash(password, salt).then((hash) => {
  hashAsync = hash;
  console.timeEnd("BcryptJS Asynchronous Hash Generate");
  console.time("BcryptJS Asynchronous Hash Compare");
  bcryptjs.compare(password, hashAsync).then((result) => {
    console.timeEnd("BcryptJS Asynchronous Hash Compare");
  });
});

Run the Script:

node index.js

Output:

BcryptJS Library Performance Output

Native Bcrypt easily wins this comparison by roughly 20% owing to the fact that running computations in C++ are much faster than doing them in JavaScript.

Dependencies Differences

As we mentioned, BcryptJS doesn’t have any native dependencies, by this we meant that it doesn’t require any C/C++ compilation so it uses the libraries and APIs already available to the JavaScript or NodeJS runtime environment. BcryptJS relies on the Crypto module on NodeJS and the Web Crypto API to generate random numbers.

However, this is not the case with the native Bcrypt library. Being native to NodeJS, it depends on the NodeJS runtime and node-gyp for compilation. This requires windows users to install options for C# and C++ installed with their visual studio instance.

Use Case and Runtime Environment Differences

Bcrypt library heavily on the NodeJS runtime environment so it is generally preferred over BcryptJS for most NodeJS applications even though they perform similar operations. Secondly, the native library cannot run on a Browser environment without a NodeJS server on the backend.

BcryptJS library can run on both NodeJS and Browser runtime environments as it’s written in JavaScript entirely and can use the Web Crypto API on browsers as a utility.

Conclusion

Both libraries have similar APIs and features when it comes to implementing the Bcrypt hashing algorithm. When it comes to the backend or server-side NodeJS Applications it is wiser to choose the Native Bcrypt library because of the significant performance advantages over BcryptJS. When it comes to using the Bcrypt algorithm on a browser without backend NodeJS support, the BcryptJS library finds itself in a better position.

However, there can be times when we may need to implement both libraries. BcryptJS won’t have much of an issue working with the native Bcrypt library because of its compatibility with the native library.

References

https://www.npmjs.com/package/bcrypt

https://www.npmjs.com/package/bcryptjs

https://nodejs.org/api/addons.html

Devdeep Ghosh
Devdeep Ghosh
Articles: 14