Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Password hashing in nodejs using built-in `crypto`

What's the best way to implement password hashing and verification in node.js using only the built-in crypto module. Basically what is needed:

function passwordHash(password) {} // => passwordHash
function passwordVerify(password, passwordHash) {} // => boolean

People usually are using bcrypt or other third-party libs for this purpose. I wonder isn't built-in crypto module huge enough already to cover at least all basic needs?

There's scrypt(), which appears to be the right guy for this purpose, but there's no verified counterpart and nobody seems to care.

like image 350
disfated Avatar asked Mar 03 '26 21:03

disfated


1 Answers

import { scrypt, randomBytes, timingSafeEqual } from "crypto";
import { promisify } from "util";

// scrypt is callback based so with promisify we can await it
const scryptAsync = promisify(scrypt);

Hashing process has two methods. First method, you hash the password, second method, you need to compare the new sign-in password with the stored password. I use typescript to write everything in detail

export class Password {

  static async hashPassword(password: string) {
    const salt = randomBytes(16).toString("hex");
    const buf = (await scryptAsync(password, salt, 64)) as Buffer;
    return `${buf.toString("hex")}.${salt}`;
  }

  static async comparePassword(
    storedPassword: string,
    suppliedPassword: string
  ): Promise<boolean> {
    // split() returns array
    const [hashedPassword, salt] = storedPassword.split(".");
    // we need to pass buffer values to timingSafeEqual
    const hashedPasswordBuf = Buffer.from(hashedPassword, "hex");
    // we hash the new sign-in password
    const suppliedPasswordBuf = (await scryptAsync(suppliedPassword, salt, 64)) as Buffer;
    // compare the new supplied password with the stored hashed password
    return timingSafeEqual(hashedPasswordBuf, suppliedPasswordBuf);
  }
}

Test it:

Password.hashPassword("123dafdas")
  .then((res) => Password.comparePassword(res, "123edafdas"))
  .then((res) => console.log(res));
like image 145
Yilmaz Avatar answered Mar 06 '26 11:03

Yilmaz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!