Password Hasher Utility

Registered members can download the FREE Get Started Apps. I initially implemented MySQL for this site and the Get Started App. The Get Started App is the project I used to compose articles about setting up VS Code and developing Node with Express and the Embedded JavaScript (EJS) view engine. I decided to migrate this site to PostgreSQL. Rather than replacing the MySQL Get Started App, I decided to add a PostgreSQL Get Started App. Both apps will run without a database but can integrate with either MySQL or PostgreSQL by configuring environment variables in the .env file.

Argon2id is the modern, recommended standard for password hashing, offering superior resistance against GPU/ASIC-based attacks due to its "memory-hard" design. While bcrypt is secure and widely supported, it is vulnerable to high-parallelism cracking hardware. Choose Argon2id for new projects, or bcrypt if, and only if, you need maximum compatibility.

This series will focus on the utilities I use for this site which implement user security and communications crucial to user registration and user password storage.

I implement the 'argon2' library to hash passwords before database storage on ExpressWithUsers.Com. This utility demonstrates implementation and functionality.

Open PowerShell or a command prompt from the project folder. Execute the npm CLI (Node Package Manager Command Line Interface) install command to install the 'argon2' library.

npm install argon2

The UtilitiesController imports the argon2 module.

utilities-controller.mjs
import argon2 from 'argon2';

The UtilitiesController passes template variables to the Password Hasher template.

utilities-controller.mjs
const password = 'P@ssw0rd';
const hashedPassword1 = await argon2.hash(password);
const verified1 = await argon2.verify(hashedPassword1, password);
const hashedPassword2 = await argon2.hash(password);
const verified2 = await argon2.verify(hashedPassword2, password);
const invalidPassword = 'InvalidPassword';
const invalidResult = await argon2.verify(hashedPassword2, invalidPassword);

The default parameters are encoded in the hash result. The v parameter specifies the RFC 9106 algorithm revision. The Memory-Constrained recommendation is 64 MiB RAM, 3 iterations, 4 parallelism.

$argon2id$v=19$m=65536,t=3,p=4$BgzYlZ6Go0S34IhcfF9T6g$/TT/fcLM+uLwgKSYjG7Rm9wdWKCbOzJ0kEnJGG6I63E

You can override the defaults with the hash constructor.

const hash = await argon2.hash("password", {
  type: argon2.argon2id,
  memoryCost: 65536, // 64 MiB
  timeCost: 3,       // 3 iterations
  parallelism: 4     // 4 threads
});
Created: 3/19/26