正在加载,请稍候…

Bcrypt Password Hashing: The Complete Developer Guide

Learn why bcrypt is the gold standard for password storage, how cost factors work, and how to verify passwords safely.

What Is bcrypt?

bcrypt is a password hashing function designed by Niels Provos and David Mazieres, presented at USENIX 1999. It remains one of the most widely recommended algorithms for hashing passwords in user authentication systems. Unlike general-purpose hash functions like MD5 or SHA-256 (which are designed to be fast), bcrypt is deliberately slow and computationally expensive — a critical property for password security.

Why bcrypt for Passwords?

The Problem with Fast Hash Functions

General cryptographic hash functions like SHA-256 are optimized for speed. Modern hardware can compute billions of SHA-256 hashes per second. This makes brute-force attacks against hashed passwords feasible:

  • A GPU can check ~10 billion MD5 hashes/second
  • If a database of SHA-256 hashed passwords is leaked, attackers can test billions of guesses per second

bcrypt's Adaptive Cost Factor

bcrypt includes a work factor (also called cost factor) that controls how computationally expensive the hash computation is. Each increment doubles the work:

  • Work factor 10: ~100ms per hash
  • Work factor 12: ~400ms per hash
  • Work factor 14: ~1.6 seconds per hash

An attacker cracking work-factor-12 bcrypt hashes can only test ~2.5 hashes per second on a GPU (compared to billions for MD5). This makes brute-force attacks computationally infeasible for strong passwords.

As hardware gets faster, you can increase the work factor to maintain security. This adaptive property is bcrypt's key advantage.

bcrypt Hash Format

A bcrypt hash looks like:

$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/AwB5RoP8YTp7vFyAu

Breaking it down:

  • $2b$ — bcrypt algorithm version (2b is the current recommended version)
  • 12 — work factor (cost factor)
  • LQv3c1yqBWVHxkd0LHAkCO — 22-character Base64-encoded salt (128 bits)
  • Yz6TtxMQJqhN8/AwB5RoP8YTp7vFyAu — 31-character Base64-encoded hash

The salt and hash are stored together in the single output string — you don't need a separate column for the salt.

The bcrypt Salting Process

A salt is random data added to the password before hashing. bcrypt generates a unique random salt for each password:

User sets password: "mysecretpassword"
Random salt:        "LQv3c1yqBWVHxkd0LHAkCO"
Hash input:         salt + password
bcrypt output:      $2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/AwB5RoP8YTp7vFyAu

Benefits of salting:

  • Prevents rainbow tables: Pre-computed hash tables are useless because each hash has a unique salt
  • Identical passwords have different hashes: Two users with "password123" get completely different bcrypt hashes
  • No need to store salt separately: The salt is embedded in the hash output

Choosing the Work Factor

OWASP recommends a work factor that takes at least 1 second on your server hardware. As hardware improves, increase the work factor accordingly.

Guidelines:

  • Interactive login (web app): 10-12 (100ms-400ms)
  • API authentication: 10-11 (acceptable latency)
  • Offline storage: 14+ (maximum security)

Test your server and choose the highest work factor that keeps authentication under your latency budget.

bcrypt in Popular Languages

Node.js (bcryptjs or bcrypt)

const bcrypt = require('bcryptjs');

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

// Verify a password
const isValid = await bcrypt.compare('myPassword', hash);

Python (bcrypt library)

import bcrypt

# Hash
password_hash = bcrypt.hashpw(b'myPassword', bcrypt.gensalt(rounds=12))

# Verify
is_valid = bcrypt.checkpw(b'myPassword', password_hash)

PHP (built-in password_hash)

// Hash
$hash = password_hash('myPassword', PASSWORD_BCRYPT, ['cost' => 12]);

// Verify
$valid = password_verify('myPassword', $hash);

bcrypt Limitations

72-Character Password Limit

bcrypt truncates input at 72 bytes. Passwords longer than 72 characters are treated identically regardless of the additional characters. Solutions: pre-hash with SHA-256 or use Argon2id instead.

Not Suitable for Non-Password Data

bcrypt is designed for passwords (human-memorable, moderate length). For encrypting arbitrary data, use AES. For API key verification, bcrypt is overkill — HMAC-SHA256 is more appropriate.

Alternatives: Argon2, scrypt

More modern alternatives:

  • Argon2id: Winner of the Password Hashing Competition (2015). Better memory-hardness. Recommended for new systems.
  • scrypt: Similar memory-hard design, used in some cryptocurrency systems.

bcrypt remains excellent for most applications due to its long track record and wide library support.

Using the bcrypt Tool

Our tool:

  1. Hash a password — enter any password and choose the work factor
  2. Verify a hash — test if a password matches an existing bcrypt hash
  3. Configure cost factor — set work factor from 4 (testing) to 14 (maximum)
  4. View timing — see how long the hash takes at the selected cost factor
  5. Copy result — one-click copy of the generated hash

Use it for testing bcrypt implementations, generating hashes for development databases, and understanding how work factors affect performance.