Password hashing using Bcrypt

Long Vu
3 min readNov 15, 2024

What Bcrypt is

Bcrypt is a widely used password hashing function designed to securely store passwords by transforming them into fixed-length strings that are difficult to reverse-engineer. Developed by Niels Provos and David Mazières in 1999, Bcrypt is based on the Blowfish cipher and incorporates both hashing and salting techniques to enhance security.

Why BCrypt is Necessary

How Bcrypt works

  • Generates a random salt
  • Combine salt with the password
  • Use a modified Blowfish key setup
  • Performs multiple rounds based on work factor
  • Produces final hash containing:
  • Algorithm version ($2a$, $2b$)
  • Work factor (cost)
  • Salt
  • Hash

Password hashing using Bcrypt

Implementation and usage

const bcrypt = require('bcrypt');

class PasswordService {
// Configuration
static SALT_ROUNDS = 12; // Work factor (2^12 iterations)

/**
* Hash a password using BCrypt
* @param {string} password - Plain text password
* @returns {Promise<string>} Hashed password
*/

static async hashPassword(password) {
try {
// Generate salt and hash password
const salt = await bcrypt.genSalt(this.SALT_ROUNDS);
const hash = await bcrypt.hash(password, salt);

// Example hash format: $2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LcdYxEGhKgUHQBSre
// $2b$ - Version
// 12 - Work factor
// 22 chars - Salt
// 31 chars - Hash
return hash;
} catch (error) {
console.error('Error hashing password:', error);
throw error;
}
}

/**
* Verify a password against its hash
* @param {string} password - Plain text password to verify
* @param {string} hash - Stored hash to compare against
* @returns {Promise<boolean>} True if password matches
*/

static async verifyPassword(password, hash) {
try {
return await bcrypt.compare(password, hash);
} catch (error) {
console.error('Error verifying password:', error);
throw error;
}
}

/**
* Example of password hash storage
*/

static async demonstratePasswordWorkflow() {
// 1. When user creates account/changes password
const userPassword = 'MySecurePassword123!';
const hashedPassword = await this.hashPassword(userPassword);

// Store hashedPassword in database
const mockDatabase = {
userId: '123',
hashedPassword: hashedPassword
};

// 2. When user attempts to login
const loginAttempt1 = 'MySecurePassword123!';
const loginAttempt2 = 'WrongPassword';

// Verify correct password
const isValid1 = await this.verifyPassword(
loginAttempt1,
mockDatabase.hashedPassword
);
console.log('Correct password:', isValid1); // true

// Verify wrong password
const isValid2 = await this.verifyPassword(
loginAttempt2,
mockDatabase.hashedPassword
);
console.log('Wrong password:', isValid2); // false
}

/**
* Demonstrate how work factor affects hashing time
*/

static async demonstrateWorkFactor() {
const password = 'test';
const workFactors = [10, 12, 14];

for (const factor of workFactors) {
const start = Date.now();
await bcrypt.hash(password, factor);
const end = Date.now();

console.log(`Work factor ${factor}: ${end - start}ms`);
}
}
}

// Example usage
async function example() {
// Hash a password
const hash = await PasswordService.hashPassword('mypassword');
console.log('Hash:', hash);

// Verify password
const isValid = await PasswordService.verifyPassword('mypassword', hash);
console.log('Password valid:', isValid);

// Demonstrate work factor timing
await PasswordService.demonstrateWorkFactor();
}

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Long Vu
Long Vu

Written by Long Vu

Product builder, Engineering Manager, AI enthusiastic

No responses yet

Write a response