43 lines
1.0 KiB
JavaScript
43 lines
1.0 KiB
JavaScript
import { randomBytes, pbkdf2Sync, randomInt } from "node:crypto";
|
|
|
|
// Settings (tune as needed)
|
|
const ITERATIONS = 100_000; // Slow enough to deter brute force
|
|
const KEYLEN = 64; // 512-bit hash
|
|
const DIGEST = "sha512";
|
|
|
|
/**
|
|
* Generate a hash from a plaintext password.
|
|
* @param {String} password
|
|
* @returns String
|
|
*/
|
|
export function hash(password) {
|
|
const salt = randomBytes(16).toString("hex"); // 128-bit salt
|
|
const hash = pbkdf2Sync(
|
|
password,
|
|
salt,
|
|
ITERATIONS,
|
|
KEYLEN,
|
|
DIGEST,
|
|
).toString("hex");
|
|
return `${ITERATIONS}:${salt}:${hash}`;
|
|
}
|
|
|
|
/**
|
|
* Verify that a password is correct against a given hash.
|
|
*
|
|
* @param {String} password
|
|
* @param {String} hashed_password
|
|
* @returns Boolean
|
|
*/
|
|
export function verify(password, hashed_password) {
|
|
const [iterations, salt, hash] = hashed_password.split(":");
|
|
const derived = pbkdf2Sync(
|
|
password,
|
|
salt,
|
|
Number(iterations),
|
|
KEYLEN,
|
|
DIGEST,
|
|
).toString("hex");
|
|
return hash === derived;
|
|
}
|