PureTools

bcrypt: The Best Way to Hash Passwords

PureTools Team· 8 min read
bcrypt: The Best Way to Hash Passwords

bcrypt: Why It's Still the Gold Standard

Storing passwords as plain text is the cardinal sin of security. Storing them as MD5 or SHA-256 hashes isn't much better — those algorithms are designed to be fast, which is exactly what you don't want for passwords.

The Problem with Fast Hashes

A modern GPU can compute:

  • MD5: ~40 billion hashes/second
  • SHA-256: ~5 billion hashes/second
  • bcrypt (cost 12): ~13,000 hashes/second

That's 4 million times slower. For a normal login (one hash), the difference is imperceptible — maybe 250ms instead of nanoseconds. For an attacker trying every possible password, it's the difference between cracking your database in an hour vs. centuries.

How bcrypt Works

bcrypt is based on the Blowfish cipher. The key innovation is the cost factor — a number that determines how many rounds of hashing to perform. Each increment doubles the computation time:

Cost~Time
10~65ms
12~250ms
14~1s
16~4s

Cost 12 is the sweet spot for most applications in 2026. As hardware gets faster, just bump the number.

The bcrypt Hash Format

$2b$12$LJ3m4lM5JEuGgPmPZv8lLOQOjR5XhFKyq8w1v6WjKQfRCg1lJfDSu
 ↑   ↑  ↑                     ↑
 alg cost  22-char salt         31-char hash

The salt is embedded in the output — no need to store it separately. Each password gets a unique salt, so identical passwords produce different hashes.

Implementation

Node.js:

import bcrypt from 'bcrypt';

// Hash a password
const hash = await bcrypt.hash('myPassword123', 12);

// Verify a password
const match = await bcrypt.compare('myPassword123', hash);
// true

Python:

import bcrypt

hashed = bcrypt.hashpw(b'myPassword123', bcrypt.gensalt(rounds=12))
match = bcrypt.checkpw(b'myPassword123', hashed)

Common Mistakes

  • Truncation: bcrypt has a 72-byte input limit. Passwords longer than that are silently truncated. Pre-hash with SHA-256 if you support long passwords.
  • Cost too low: Cost 4 is basically no protection. Use 12 minimum.
  • Rolling your own: Don't implement bcrypt yourself. Use the well-tested library for your language.

Alternatives

Argon2 won the Password Hashing Competition in 2015 and is technically superior — it's memory-hard (resistant to GPU attacks). But bcrypt has 25+ years of battle-testing and universal library support. Both are excellent choices.

Try it: bcrypt Generator — hash passwords with configurable cost factor.