Minor tweaks and renames
This commit is contained in:
@@ -2,22 +2,18 @@ import { randomBytes, pbkdf2Sync } from "node:crypto";
|
|||||||
import { Config } from "../config.js";
|
import { Config } from "../config.js";
|
||||||
|
|
||||||
// Settings (tune as needed)
|
// Settings (tune as needed)
|
||||||
const ITERATIONS = 1000;
|
const ITERATIONS = 1000; // MAGIC CONSTANT - move to Config
|
||||||
const KEYLEN = 32; // 32-bit hash
|
const DIGEST = "sha256"; // MAGIC CONSTANT - move to Config
|
||||||
const DIGEST = "sha256";
|
const KEYLEN = 32; // MAGIC CONSTANT - move to Config
|
||||||
const DEV = process.env.NODE_ENV === "dev";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a hash from a plaintext password.
|
* Generate a hash from a string
|
||||||
* @param {string} password
|
* @param {string} source @returns {string}
|
||||||
* @returns {string}
|
|
||||||
*/
|
*/
|
||||||
export function generateHash(password) {
|
export function generateHash(source) {
|
||||||
const salt = randomBytes(16).toString("hex"); // 128-bit salt
|
const salt = randomBytes(16).toString("hex"); // 128-bit salt
|
||||||
const hash = pbkdf2Sync(password, salt, ITERATIONS, KEYLEN, DIGEST).toString(
|
const hash = pbkdf2Sync(source, salt, ITERATIONS, KEYLEN, DIGEST).toString("hex");
|
||||||
"hex",
|
return `${ITERATIONS}:${salt}:${hash}`;
|
||||||
);
|
|
||||||
return `${ITERATIONS}:${salt}:${hash}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,41 +24,35 @@ export function generateHash(password) {
|
|||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export function verifyPassword(password_candidate, stored_password_hash) {
|
export function verifyPassword(password_candidate, stored_password_hash) {
|
||||||
const [iterations, salt, hash] = stored_password_hash.split(":");
|
const [iterations, salt, hash] = stored_password_hash.split(":");
|
||||||
const derived = pbkdf2Sync(
|
const derived = pbkdf2Sync(password_candidate, salt, Number(iterations), KEYLEN, DIGEST).toString("hex");
|
||||||
password_candidate,
|
const success = hash === derived;
|
||||||
salt,
|
if (Config.dev) {
|
||||||
Number(iterations),
|
console.debug(
|
||||||
KEYLEN,
|
"Verifying password:\n" +
|
||||||
DIGEST,
|
" Input : %s (the password as it was sent to us by the client)\n" +
|
||||||
).toString("hex");
|
" Given : %s (the input password hashed by us (not necessary for validation))\n" +
|
||||||
const success = hash === derived;
|
" Stored : %s (the password hash we have on file for the player)\n" +
|
||||||
if (Config.dev || true) {
|
" Derived : %s (the hashed version of the input password)\n" +
|
||||||
console.debug(
|
" Verified : %s (was the password valid)",
|
||||||
"Verifying password:\n" +
|
password_candidate,
|
||||||
" Input : %s (the password as it was sent to us by the client)\n" +
|
generateHash(password_candidate),
|
||||||
" Given : %s (the input password hashed by us (not necessary for validation))\n" +
|
stored_password_hash,
|
||||||
" Stored : %s (the password hash we have on file for the player)\n" +
|
derived,
|
||||||
" Derived : %s (the hashed version of the input password)\n" +
|
success,
|
||||||
" Verified : %s (was the password valid)",
|
);
|
||||||
password_candidate,
|
}
|
||||||
generateHash(password_candidate),
|
return success;
|
||||||
stored_password_hash,
|
|
||||||
derived,
|
|
||||||
success,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param {string} candidate */
|
/** @param {string} candidate */
|
||||||
export function isUsernameSane(candidate) {
|
export function isUsernameSane(candidate) {
|
||||||
return /^[a-zA-Z0-9_]{4,}$/.test(candidate);
|
return Config.usernameSanityRegex.test(candidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param {string} candidate */
|
/** @param {string} candidate */
|
||||||
export function isPasswordSane(candidate) {
|
export function isPasswordSane(candidate) {
|
||||||
// We know the password must adhere to one of our client-side-hashed crypto schemes,
|
// We know the password must adhere to one of our client-side-hashed crypto schemes,
|
||||||
// so we can be fairly strict with the allowed passwords
|
// so we can be fairly strict with the allowed passwords
|
||||||
return /^[a-zA-Z0-9_: -]{8,}$/.test(candidate);
|
return Config.passwordSanityRegex.test(candidate);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user