bcryptjs vs crypto-js vs node-forge vs sjcl
JavaScript Cryptography Libraries
bcryptjscrypto-jsnode-forgesjclSimilar Packages:

JavaScript Cryptography Libraries

Cryptography libraries in JavaScript provide developers with tools to secure data through encryption, hashing, and other security protocols. These libraries are essential for protecting sensitive information, ensuring data integrity, and implementing secure authentication mechanisms in web applications. The choice of library can significantly impact the security and performance of an application, making it crucial to understand the strengths and weaknesses of each option available.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
bcryptjs03,792112 kB35 months agoBSD-3-Clause
crypto-js016,398487 kB2782 years agoMIT
node-forge05,2841.65 MB45511 days ago(BSD-3-Clause OR GPL-2.0)
sjcl07,2232.24 MB11717 days ago(BSD-2-Clause OR GPL-2.0-only)

Feature Comparison: bcryptjs vs crypto-js vs node-forge vs sjcl

Primary Use Case

  • bcryptjs:

    bcryptjs is primarily used for securely hashing passwords. It is designed to be slow to thwart brute-force attacks, making it ideal for user authentication systems.

  • crypto-js:

    crypto-js is a general-purpose cryptography library that supports multiple encryption and hashing algorithms, making it suitable for a wide range of applications including data encryption and integrity verification.

  • node-forge:

    node-forge is a comprehensive library that can handle various cryptographic tasks such as encryption, decryption, and certificate management, making it suitable for applications that require secure communications and data protection.

  • sjcl:

    sjcl is focused on client-side encryption and is optimized for performance and security, making it ideal for applications that need to encrypt data in the browser.

Performance

  • bcryptjs:

    bcryptjs is slower than many other hashing algorithms due to its design, which is intentional to enhance security. This makes it less suitable for scenarios requiring high-speed hashing but excellent for password storage.

  • crypto-js:

    crypto-js offers a balance between performance and security, allowing for fast encryption and decryption processes. However, performance can vary based on the chosen algorithm.

  • node-forge:

    node-forge is relatively performant but can be slower than specialized libraries for specific tasks due to its comprehensive feature set. It is best used where flexibility is needed over raw speed.

  • sjcl:

    sjcl is designed for performance and is lightweight, making it suitable for client-side applications where speed is essential without sacrificing security.

Security Features

  • bcryptjs:

    bcryptjs includes built-in salting and is resistant to rainbow table attacks, making it a secure choice for password hashing.

  • crypto-js:

    crypto-js provides a variety of encryption algorithms, but developers must ensure proper implementation to avoid vulnerabilities. It does not include built-in salting for hashes, requiring additional care.

  • node-forge:

    node-forge supports various cryptographic standards and protocols, providing a robust security framework for applications that require secure communications.

  • sjcl:

    sjcl implements modern cryptographic algorithms and practices, ensuring strong security for client-side encryption, but developers must be cautious about potential pitfalls in implementation.

Ease of Use

  • bcryptjs:

    bcryptjs has a straightforward API specifically for password hashing, making it easy to implement for developers focused on authentication.

  • crypto-js:

    crypto-js has a more complex API due to its wide range of features, which may require a steeper learning curve for new users.

  • node-forge:

    node-forge offers a comprehensive API that can be complex for beginners but provides extensive documentation to assist developers in implementation.

  • sjcl:

    sjcl is designed to be easy to use with a simple API, making it accessible for developers looking to implement encryption quickly.

Community and Support

  • bcryptjs:

    bcryptjs has a strong community and is widely used, ensuring good support and documentation available for developers.

  • crypto-js:

    crypto-js is also widely used, with a decent community and resources, but may not have as extensive support as some other libraries.

  • node-forge:

    node-forge has a dedicated community and is actively maintained, providing good support and updates for developers.

  • sjcl:

    sjcl has a smaller community compared to others, but it is well-documented and supported by its maintainers, making it reliable for developers.

How to Choose: bcryptjs vs crypto-js vs node-forge vs sjcl

  • bcryptjs:

    Choose bcryptjs if you need a reliable solution for hashing passwords securely. It is specifically designed for this purpose and implements the bcrypt hashing algorithm, which is resistant to brute-force attacks and includes a salt to enhance security.

  • crypto-js:

    Select crypto-js for a versatile library that supports various encryption algorithms and hashing functions. It is suitable for applications that require both symmetric and asymmetric encryption, as well as hashing, and is easy to integrate into existing projects.

  • node-forge:

    Opt for node-forge if you need a comprehensive toolkit for implementing cryptographic protocols, including TLS. It provides a wide range of features, including certificate generation and management, making it ideal for applications that require complex cryptographic operations.

  • sjcl:

    Choose sjcl for a lightweight and efficient library focused on modern cryptographic algorithms. It is particularly useful for client-side encryption and offers a simple API for developers looking to implement cryptography without the overhead of larger libraries.

README for bcryptjs

bcrypt.js

Optimized bcrypt in JavaScript with zero dependencies, with TypeScript support. Compatible to the C++ bcrypt binding on Node.js and also working in the browser.

Build Status Publish Status npm

Security considerations

Besides incorporating a salt to protect against rainbow table attacks, bcrypt is an adaptive function: over time, the iteration count can be increased to make it slower, so it remains resistant to brute-force search attacks even with increasing computation power. (see)

While bcrypt.js is compatible to the C++ bcrypt binding, it is written in pure JavaScript and thus slower (about 30%), effectively reducing the number of iterations that can be processed in an equal time span.

The maximum input length is 72 bytes (note that UTF-8 encoded characters use up to 4 bytes) and the length of generated hashes is 60 characters. Note that maximum input length is not implicitly checked by the library for compatibility with the C++ binding on Node.js, but should be checked with bcrypt.truncates(password) where necessary.

Usage

The package exports an ECMAScript module with an UMD fallback.

$> npm install bcryptjs
import bcrypt from "bcryptjs";

Usage with a CDN

  • From GitHub via jsDelivr:
    https://cdn.jsdelivr.net/gh/dcodeIO/bcrypt.js@TAG/index.js (ESM)
  • From npm via jsDelivr:
    https://cdn.jsdelivr.net/npm/bcryptjs@VERSION/index.js (ESM)
    https://cdn.jsdelivr.net/npm/bcryptjs@VERSION/umd/index.js (UMD)
  • From npm via unpkg:
    https://unpkg.com/bcryptjs@VERSION/index.js (ESM)
    https://unpkg.com/bcryptjs@VERSION/umd/index.js (UMD)

Replace TAG respectively VERSION with a specific version or omit it (not recommended in production) to use latest.

When using the ESM variant in a browser, the crypto import needs to be stubbed out, for example using an import map. Bundlers should omit it automatically.

Usage - Sync

To hash a password:

const salt = bcrypt.genSaltSync(10);
const hash = bcrypt.hashSync("B4c0/\/", salt);
// Store hash in your password DB

To check a password:

// Load hash from your password DB
bcrypt.compareSync("B4c0/\/", hash); // true
bcrypt.compareSync("not_bacon", hash); // false

Auto-gen a salt and hash:

const hash = bcrypt.hashSync("bacon", 10);

Usage - Async

To hash a password:

const salt = await bcrypt.genSalt(10);
const hash = await bcrypt.hash("B4c0/\/", salt);
// Store hash in your password DB
bcrypt.genSalt(10, (err, salt) => {
  bcrypt.hash("B4c0/\/", salt, function (err, hash) {
    // Store hash in your password DB
  });
});

To check a password:

// Load hash from your password DB
await bcrypt.compare("B4c0/\/", hash); // true
await bcrypt.compare("not_bacon", hash); // false
// Load hash from your password DB
bcrypt.compare("B4c0/\/", hash, (err, res) => {
  // res === true
});
bcrypt.compare("not_bacon", hash, (err, res) => {
  // res === false
});

Auto-gen a salt and hash:

await bcrypt.hash("B4c0/\/", 10);
// Store hash in your password DB
bcrypt.hash("B4c0/\/", 10, (err, hash) => {
  // Store hash in your password DB
});

Note: Under the hood, asynchronous APIs split an operation into small chunks. After the completion of a chunk, the execution of the next chunk is placed on the back of the JS event queue, efficiently yielding for other computation to execute.

Usage - Command Line

Usage: bcrypt <input> [rounds|salt]

API

Callback types

  • Callback<T>: (err: Error | null, result?: T) => void
    Called with an error on failure or a value of type T upon success.

  • ProgressCallback: (percentage: number) => void
    Called with the percentage of rounds completed (0.0 - 1.0), maximally once per MAX_EXECUTION_TIME = 100 ms.

  • RandomFallback: (length: number) => number[]
    Called to obtain random bytes when both Web Crypto API and Node.js crypto are not available.

Functions

  • bcrypt.genSaltSync(rounds?: number): string
    Synchronously generates a salt. Number of rounds defaults to 10 when omitted.

  • bcrypt.genSalt(rounds?: number): Promise<string>
    Asynchronously generates a salt. Number of rounds defaults to 10 when omitted.

  • bcrypt.genSalt([rounds: number, ]callback: Callback<string>): void
    Asynchronously generates a salt. Number of rounds defaults to 10 when omitted.

  • bcrypt.truncates(password: string): boolean
    Tests if a password will be truncated when hashed, that is its length is greater than 72 bytes when converted to UTF-8.

  • bcrypt.hashSync(password: string, salt?: number | string): string Synchronously generates a hash for the given password. Number of rounds defaults to 10 when omitted.

  • bcrypt.hash(password: string, salt: number | string): Promise<string>
    Asynchronously generates a hash for the given password.

  • bcrypt.hash(password: string, salt: number | string, callback: Callback<string>, progressCallback?: ProgressCallback): void
    Asynchronously generates a hash for the given password.

  • bcrypt.compareSync(password: string, hash: string): boolean
    Synchronously tests a password against a hash.

  • bcrypt.compare(password: string, hash: string): Promise<boolean>
    Asynchronously compares a password against a hash.

  • bcrypt.compare(password: string, hash: string, callback: Callback<boolean>, progressCallback?: ProgressCallback)
    Asynchronously compares a password against a hash.

  • bcrypt.getRounds(hash: string): number
    Gets the number of rounds used to encrypt the specified hash.

  • bcrypt.getSalt(hash: string): string
    Gets the salt portion from a hash. Does not validate the hash.

  • bcrypt.setRandomFallback(random: RandomFallback): void
    Sets the pseudo random number generator to use as a fallback if neither Web Crypto API nor Node.js crypto are available. Please note: It is highly important that the PRNG used is cryptographically secure and that it is seeded properly!

Building

Building the UMD fallback:

$> npm run build

Running the tests:

$> npm test

Credits

Based on work started by Shane Girish at bcrypt-nodejs, which is itself based on javascript-bcrypt (New BSD-licensed).