bcrypt Password Hashing Examples — Node.js and Python

💡bcrypt hashes passwords by running them through a slow key derivation function with a random salt. The output includes the algorithm, cost factor, salt, and hash in one string. To verify a password, run bcrypt.compare() — never compare hashes directly. Generate and test bcrypt hashes with the bcrypt Generator tool.

Examples

Hash a password (Node.js)

❌ Wrong

const hash = crypto.createHash('sha256').update(password).digest('hex');

✅ Fixed

const hash = await bcrypt.hash(password, 12);

SHA-256 is fast — bad for passwords. bcrypt is intentionally slow to resist brute force.

Verify a password

❌ Wrong

const valid = hash === bcrypt.hashSync(inputPassword, salt);

✅ Fixed

const valid = await bcrypt.compare(inputPassword, storedHash);

Never re-hash and compare — use bcrypt.compare(). It handles salt extraction from the stored hash.

Async vs sync usage

❌ Wrong

const hash = bcrypt.hashSync(password, 12); // blocks event loop

✅ Fixed

const hash = await bcrypt.hash(password, 12); // non-blocking

hashSync blocks the Node.js event loop during hashing. Always use the async version in production.

Wrong salt rounds

❌ Wrong

bcrypt.hash(password, bcrypt.genSaltSync(4)); // too weak

✅ Fixed

bcrypt.hash(password, 12); // strong and fast enough

4 rounds is too fast to provide real security. 10-12 is recommended. Each increment doubles compute time.

Generate bcrypt Hashes

Real-World Usage

User registration in Node.js

const bcrypt = require('bcrypt');
const SALT_ROUNDS = 12;

async function hashPassword(password) {
  return bcrypt.hash(password, SALT_ROUNDS);
}

12 rounds is a good balance of security and performance for 2024+.

Login verification

async function verifyPassword(password, hash) {
  const match = await bcrypt.compare(password, hash);
  if (!match) throw new Error('Invalid credentials');
}

bcrypt.compare() handles the salt extraction automatically — never compare strings.

Python with bcrypt library

import bcrypt

password = b'mysecretpassword'
hashed = bcrypt.hashpw(password, bcrypt.gensalt(rounds=12))
print(hashed)  # b'$2b$12$...'

# Verify
bcrypt.checkpw(password, hashed)

Python bcrypt requires bytes. Encode strings with .encode('utf-8') before hashing.

Related Guides

Frequently Asked Questions

What does the bcrypt output string mean?

$2b$12$randomsalthashvalue — $2b$ is algorithm version, 12 is cost factor (rounds), next 22 chars are salt, rest is hash. Everything needed for verification is in this one string.

How many bcrypt rounds should I use?

Use rounds that make hashing take ~100-300ms on your hardware. As of 2024, 12 rounds is a common recommendation. Benchmark on your server: higher is better security but slower login.

Can two identical passwords produce different bcrypt hashes?

Yes. bcrypt generates a new random salt each time. The same password produces a different hash on every call. bcrypt.compare() handles this — it extracts the salt from the stored hash.

All tools run in your browser. Your data never leaves your device.