bcrypt

bcrypt is a password hashing function designed to be computationally expensive, making brute-force attacks impractical. It incorporates a salt and configurable work factor, automatically adapting to increased computing power over time.

How bcrypt Works

bcrypt uses the Blowfish cipher in a key setup phase that is deliberately slow. The work factor (cost) determines how many iterations are performed, with each increment doubling the computation time.

bcrypt Hash Format

$2b$12$R9h/cIPz0gi.URNNX3kh2OPST9/PgBkqquzi.Ss7KIUgO2t0jWMUW
 │  │  │                      │
 │  │  │                      └── Hash (31 characters)
 │  │  └── Salt (22 characters, base64)
 │  └── Cost factor (2^12 = 4096 iterations)
 └── Algorithm version ($2a$, $2b$, $2y$)

Usage Example

# Python
import bcrypt

# Hash a password
password = b"secretpassword"
salt = bcrypt.gensalt(rounds=12)  # Cost factor
hashed = bcrypt.hashpw(password, salt)

# Verify password
if bcrypt.checkpw(password, hashed):
    print("Password matches")

Cost Factor Selection

  • 10: ~100ms (minimum recommended)
  • 12: ~250ms (good default)
  • 14: ~1 second (high security)
  • Choose based on acceptable login delay

Why bcrypt?

  • Built-in salt prevents rainbow table attacks
  • Configurable cost adapts to hardware improvements
  • Blowfish's data-dependent S-box lookups create irregular memory access patterns, making GPU parallelization less effective
  • Widely implemented and well-tested

bcrypt vs Memory-Hard Functions

Note: bcrypt is NOT memory-hard like scrypt or Argon2. Its GPU resistance comes from Blowfish's 4KB S-box requiring frequent random memory accesses (latency-bound), not from consuming large amounts of memory. For maximum resistance to modern hardware attacks, consider Argon2id.

See Also