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.
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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With