Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js password hashing bcrypt alternative using crypto

I'm actually using bcrypt module to hash and compare hashed passwords.

What i would like to do is to remove the bcrypt module and use the default crypto library both for hashing and comparing passwords.

Is this possible?

Will this be less safe than using node-bcrypt?

Do you have any example/tutorial/doc/link on how to do?

or example i'm doing like this actually:

bcrypt.hash(string,secret_key)
bcrypt.compare(string,string,secret_key);

i just would like to replicate this with crypto if possible:

crypto.hash(string,secret_key)
    crypto.compare(string,string,secret_key);
like image 236
itsme Avatar asked Apr 02 '14 18:04

itsme


People also ask

Should I use crypto or bcrypt?

bcrypt and crypto are both open source tools. It seems that bcrypt with 6.08K GitHub stars and 426 forks on GitHub has more adoption than crypto with 17 GitHub stars and 18 GitHub forks.

Is crypto a password generator for Node JS?

Crypto module for Node JS helps developers to hash user password. To demonstrate the use of Crypto module, we can create a simple login and signup API and test it using Postman.

Is bcrypt a cryptographic hash function?

bcrypt is a password-hashing function designed by Niels Provos and David Mazières, based on the Blowfish cipher and presented at USENIX in 1999.

What is better than bcrypt?

SCrypt is a better choice today: better design than BCrypt (especially in regards to memory hardness) and has been in the field for 10 years. On the other hand, it has been used for many cryptocurrencies and we have a few hardware (both FPGA and ASIC) implementation of it.


3 Answers

You can hash using pbkdf2 from the crypto library:

crypto.pbkdf2(password, salt, iterations, keylen, digest, callback)

Sample implementation:

const crypto = require('crypto');
crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', (err, derivedKey) => {
  if (err) throw err;
  console.log(derivedKey.toString('hex'));  // '3745e48...aa39b34'
});

here goes the reference: https://nodejs.org/api/crypto.html#crypto_crypto_pbkdf2_password_salt_iterations_keylen_digest_callback

It uses HMAC digest algorithm such as sha512 to derive a key of given length from the given password, salt and iterations. Pbkdf2 has similar slowness features like bcrypt. With PBKDF2, bcrypt, or scrypt, the attacker can only make a few thousand guesses per second (or less, depending on the configuration).

like image 119
Masum Avatar answered Nov 15 '22 13:11

Masum


bcrypt will be more secure than crypto, simply because it's slower. However, here are some password functions I wrote in coffeescript using crypto (I join the create_password parts with a '$', you'll see that split in check_password):

  create_password = function(passwd, method, salt) {
    var hmac;
    method || (method = "sha1");
    salt || (salt = crypto.randomBytes(6).toString('base64'));
    hmac = crypto.createHmac(method, salt);
    hmac.end(passwd);
    return {
      hash: hmac.read().toString('hex'),
      salt: salt,
      method: method
    };
  };

  check_password = function(hashed, passwd) {
    var hash, hashp, method, salt, _ref;
    _ref = hashed.split("$"), method = _ref[0], salt = _ref[1], hashp = _ref[2];
    hash = create_password(passwd, method, salt).hash;
    return hash === hashp;
  };

Example usage:

passwd = "SOME STRING HERE"
hash_parts = create_password(passwd)
hashed = pwd_parts.method + "$" + pwd_parts.salt + "$" + pwd_parts.hash
check_password(hashed, passwd)
like image 26
Tim Brown Avatar answered Nov 15 '22 12:11

Tim Brown


As of 24th April 2020 There is a nice built in way of hashing passwords using scrypt in the crypto module. Its very secure since it utilizes a salt for hashing the password and its based off scrypt

// built right into nodejs
const crypto = require("crypto");

// salt - any random string here (ideally should be above 16 bytes)
const salt = "EoAZAJtVDdzPZmOxpx0EnqLmREYUfq";
function getHash() {
  return crypto.scryptSync("your-password-here", salt, 32).toString("hex");
}

Note: i used 32 characters in length but you can specify your desired length

like image 22
Malik Bagwala Avatar answered Nov 15 '22 14:11

Malik Bagwala