Bcrypt vs Argon2: Password Hashing Best Practices
Compare Bcrypt and Argon2 password hashing algorithms. Review CPU-hardness, memory-hardness, and resistance to GPU/ASIC brute-force attacks.
Bcrypt (CPU-Hard)
Option ALaunch the live utility to execute calculations, format payloads, or inspect outputs locally in your browser.
Argon2 (Memory-Hard)
Option BLaunch the live utility to run parallel benchmarks, test parameters, or process data offline.
๐ Feature Comparison Matrix
| Specification / Feature | Bcrypt (CPU-Hard) | Argon2 (Memory-Hard) |
|---|---|---|
| Algorithm Type | CPU-bound key-derivation (Blowfish-based) | Memory-hard key-derivation (PHC Winner) |
| Attack Resistance | Good | Excellent (resists GPU/ASIC acceleration) |
| Configuration Inputs | Work Factor (Cost) | Memory, Time/Iterations, and Parallelism |
| Adoption Date | 1999 | 2015 (Updated in 2019) |
๐ก Verdict & Architectural Recommendation
Use Argon2id (winner of the Password Hashing Competition) for all new systems as it provides memory-hardness resisting GPU attacks. Use Bcrypt for legacy systems or environments where Argon2 is not native.
๐ How Password Hashing Algorithms Work
๐ก Bcrypt (Blowfish-based)
Key Derivation Function
Based on the expensive key setup phase of the Blowfish cipher, iteratively hashing the password and salt through multiple rounds (2^cost iterations)
Cost Factor (Work Factor)
Single parameter controlling computational difficulty. Cost of 12 = 4,096 rounds, cost of 14 = 16,384 rounds. Each increment doubles the time.
CPU-Bound Design
Primarily CPU-intensive with minimal memory requirements (~4 KB). Does not significantly resist GPU parallelization attacks.
Output Format
$2b$12$R9h/cIPz0gi.URNNX3kh2OPST9/PgBkqquzi.Ss7KIUgO2t0jWMUW
๐ง Argon2 (Memory-Hard)
Memory-Hard Construction
Winner of the 2015 Password Hashing Competition. Fills large memory blocks with pseudorandom data, forcing attackers to allocate RAM proportional to the memory cost parameter.
Three Parameters (m_cost, t_cost, p)
Memory cost (19-47 MiB recommended), time iterations (2-4 passes), and parallelism degree (CPU cores). Provides fine-grained security tuning.
GPU/ASIC Resistance
High memory bandwidth requirements make parallel GPU attacks exponentially more expensive. Memory cost directly translates to attacker hardware costs.
Output Format
$argon2id$v=19$m=65536,t=3,p=4$c29tZXNhbHQ$RdescudvJCsgt...
๐ก๏ธ Attack Resistance & Security Trade-offs
๐ด Brute-Force GPU Attacks
Bcrypt
โ ๏ธ Moderate Resistance: GPUs can compute ~100,000 bcrypt hashes/sec (RTX 4090). Cost factor 12-14 provides adequate defense but not optimal against dedicated attackers with GPU farms.
Argon2
โ Excellent Resistance: Memory cost of 47 MiB limits GPU to ~8-16 parallel hashes (vs thousands for bcrypt). Attackers need proportional RAM, drastically increasing hardware costs.
๐ฐ ASIC Attack Economics
Bcrypt
Custom ASIC chips can be built to accelerate bcrypt significantly (similar to Bitcoin mining ASICs). Once manufactured, attackers gain massive speed advantages.
Argon2
Memory-hard design makes ASIC acceleration impractical - memory chips cannot be significantly sped up. Attack costs scale linearly with memory requirements.
๐ OWASP Password Storage Cheat Sheet Ranking
- 1.Argon2id - Top recommendation for all new systems (memory-hard, GPU-resistant)
- 2.scrypt - Memory-hard alternative, good but less flexible than Argon2
- 3.bcrypt - Acceptable for legacy systems, CPU-bound only
- 4.PBKDF2 - Minimum acceptable standard, outclassed by options above
โ๏ธ Recommended Configuration Parameters (2024)
Bcrypt Configuration
Cost Factor (Rounds)
Code Example (Node.js)
const bcrypt = require('bcrypt');
const saltRounds = 12; // Cost factor
// Hash password
const hash = await bcrypt.hash(
password,
saltRounds
);
// Verify password
const isValid = await bcrypt.compare(
password,
hash
);Argon2id Configuration
OWASP 2023 Parameters
Code Example (Node.js)
const argon2 = require('argon2');
// Hash password
const hash = await argon2.hash(password, {
type: argon2.argon2id,
memoryCost: 47104, // 47 MiB
timeCost: 3,
parallelism: 4
});
// Verify password
const isValid = await argon2.verify(
hash,
password
);๐ Migration Strategy: Bcrypt โ Argon2
Migrating from Bcrypt to Argon2 without forcing password resets requires a hybrid authentication approach. Here's the recommended zero-downtime migration path:
Add Hybrid Hash Detection
Update authentication middleware to detect hash type by prefix: $2a$/$2b$ for Bcrypt, $argon2id$ for Argon2
Keep Existing Bcrypt Hashes
Do NOT re-hash existing passwords in database. Continue verifying old Bcrypt hashes normally to maintain seamless user experience.
Opportunistic Re-Hashing on Login
When users successfully authenticate with Bcrypt hash, immediately re-hash their password with Argon2 and update database. This migrates active users gradually over time.
Use Argon2 for All New Accounts
Registration and password reset flows generate Argon2id hashes exclusively. New users immediately benefit from stronger security.
Monitor Migration Progress
Track percentage of accounts migrated to Argon2. After 6-12 months, ~80-90% of active users typically migrate naturally through login.
Handle Inactive Accounts
For dormant accounts still using Bcrypt after 12+ months: either keep Bcrypt indefinitely (acceptable) or force password reset on next login (increases security).
โ Frequently Asked Questions
What is the difference between Bcrypt and Argon2?โผ
Bcrypt is a CPU-bound password hashing algorithm based on the Blowfish cipher (created in 1999) that uses adaptive key derivation with configurable work factor rounds. Argon2 is a memory-hard password hashing algorithm (winner of the 2015 Password Hashing Competition) that resists GPU and ASIC attacks through high memory requirements, with configurable memory cost, time iterations, and parallelism parameters. Argon2id variant combines data-independent and data-dependent memory access for optimal security.
When should I use Bcrypt vs Argon2?โผ
Use Argon2id for all new systems as it provides superior resistance to GPU/ASIC brute-force attacks through memory-hardness and is recommended by OWASP as the top-tier password hashing algorithm. Use Bcrypt for legacy systems where Argon2 libraries are unavailable, environments with memory constraints, or when maintaining backward compatibility with existing Bcrypt hashes. Both are significantly better than plain SHA-256 or MD5 for password storage.
How does Argon2 resist GPU attacks better than Bcrypt?โผ
Argon2's memory-hard design forces attackers to allocate large amounts of RAM (configurable from 32 MB to 4 GB per hash), making parallel GPU cracking exponentially more expensive. GPUs have limited memory bandwidth and capacity compared to computation power, so memory-bound operations neutralize their advantage. Bcrypt is CPU-bound but not memory-hard, allowing GPUs to run thousands of parallel hash operations efficiently. Argon2's memory cost parameter (m_cost) directly translates to attacker hardware costs, providing better defense against modern cracking techniques.
Can I migrate from Bcrypt to Argon2 without resetting user passwords?โผ
Yes, using a phased hybrid approach: (1) Keep existing Bcrypt hashes intact and verify them normally, (2) Update authentication logic to detect hash type by prefix ($2a$/$2b$ for Bcrypt, $argon2id$ for Argon2), (3) When users successfully authenticate with Bcrypt, re-hash their password with Argon2 and store the new hash, (4) Gradually migrate users as they log in naturally over 6-12 months, (5) For inactive accounts, force password reset or keep Bcrypt indefinitely. This zero-downtime migration preserves user experience while improving security incrementally.
What are the recommended configuration parameters for Bcrypt and Argon2?โผ
For Bcrypt: Use cost factor 12-14 (2^12 to 2^14 rounds = 4,096 to 16,384 iterations) targeting 250-500ms hash time on production hardware. For Argon2id (OWASP 2023 recommendations): memory cost (m_cost) = 19 MiB minimum (47 MiB recommended), time cost (t_cost) = 2 iterations minimum (3-4 recommended), parallelism (p) = 1 thread minimum (number of CPU cores available recommended), salt = 16 bytes minimum cryptographically random. Adjust parameters based on hardware performance to maintain ~500ms-1s hash time, balancing security against user experience and server load.