25 lines
826 B
JavaScript
25 lines
826 B
JavaScript
import { pbkdf2Sync, randomBytes, timingSafeEqual } from "node:crypto";
|
|
|
|
const iterations = 120000;
|
|
const keyLength = 32;
|
|
const digest = "sha256";
|
|
|
|
export function hashPassword(password) {
|
|
const salt = randomBytes(16).toString("hex");
|
|
const hash = pbkdf2Sync(password, salt, iterations, keyLength, digest).toString("hex");
|
|
return `pbkdf2:${iterations}:${salt}:${hash}`;
|
|
}
|
|
|
|
export function verifyPassword(password, storedHash) {
|
|
const [scheme, storedIterations, salt, hash] = storedHash.split(":");
|
|
|
|
if (scheme !== "pbkdf2" || !storedIterations || !salt || !hash) {
|
|
return false;
|
|
}
|
|
|
|
const candidate = pbkdf2Sync(password, salt, Number(storedIterations), keyLength, digest);
|
|
const expected = Buffer.from(hash, "hex");
|
|
|
|
return candidate.length === expected.length && timingSafeEqual(candidate, expected);
|
|
}
|