Password hashing is critical for protecting user credentials. Unlike encryption, hashing is one-way—passwords cannot be recovered, only verified.
Algorithm Comparison
| Algorithm | Memory | Speed | Recommendation |
|---|---|---|---|
| Argon2id | Configurable | Slowest | ✅ Best choice |
| bcrypt | 4KB | Slow | ✅ Excellent |
| PBKDF2 | Minimal | Moderate | ⚠️ OK if required |
| SHA-256 (raw) | Minimal | Fast | ❌ Never use alone |
| MD5 | Minimal | Very fast | ❌ Broken |
Implementation
# Python - Argon2 (recommended)
from argon2 import PasswordHasher
ph = PasswordHasher()
hash = ph.hash("password123")
ph.verify(hash, "password123") # Returns True or raises
# Python - bcrypt
import bcrypt
hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
bcrypt.checkpw(password.encode(), hash) # Returns True/False
# Node.js - bcrypt
const bcrypt = require('bcrypt');
const hash = await bcrypt.hash(password, 12);
await bcrypt.compare(password, hash);
Common Mistakes
- Using MD5 or SHA1 alone (no salt, too fast)
- Using the same salt for all passwords
- Low iteration/work factor
- Storing passwords in plain text
Best Practices
- Use Argon2id or bcrypt
- Unique random salt per password (automatic with bcrypt/argon2)
- Increase work factor over time
- Enforce strong password policies
December 2024