bcrypt vs Argon2 vs scrypt

Updated:

Storing user passwords with raw SHA-256 is a known mistake — SHA-256 is too fast, and a stolen hash file can be brute-forced at billions of guesses per second on commodity GPUs. The industry response is purpose-built password hashing functions: bcrypt (1999), scrypt (2009), and Argon2 (2015). They are deliberately slow and increasingly memory-hard to make brute force expensive. This guide compares them on design goals, attack resistance, and the practical considerations that decide which one your team should use.

Why password hashing is different from general hashing

SHA-256 is designed to be fast. That speed is exactly what makes it dangerous for passwords: an attacker with a stolen password database can compute billions of SHA-256 hashes per second on a single GPU. Password hashing functions are deliberately slow (typically 100 ms per hash) and require memory (which is much more expensive than CPU). The goal is to make brute-force economically infeasible, not impossible.

bcrypt — the venerable workhorse

bcrypt was created in 1999 based on the Blowfish cipher. It has a tunable cost factor (the 'work factor') that doubles the computation time for each increment. As of 2026, a cost factor of 12–14 is reasonable. bcrypt is supported in virtually every language, and decades of cryptanalysis have not produced practical attacks. The downside: bcrypt's memory usage is fixed and small, so GPUs and FPGAs can attack it relatively efficiently.

scrypt — the memory-hard pioneer

scrypt was designed in 2009 specifically to resist hardware-accelerated attacks. It requires a large amount of memory to compute (tunable, typically 16–64 MB per hash), which makes GPU and ASIC attacks much harder because memory is expensive on those platforms. The trade-offs: configuration is more complex (three parameters: N, r, p), and the increased memory usage can be a problem on memory-constrained servers.

Argon2 — the modern winner

Argon2 won the Password Hashing Competition in 2015 and is now the recommended default. There are three variants: Argon2d (data-dependent, fast but vulnerable to side-channel attacks), Argon2i (data-independent, safer for shared-memory environments), and Argon2id (a hybrid recommended for most uses). Argon2 is the most flexible (tunable memory, time, and parallelism), the most modern, and the strongest against currently-known attacks.

Comparison table

  • bcrypt: 1999, time-cost only, ~4 KB memory, widely supported.
  • scrypt: 2009, memory-hard, configurable N/r/p, harder to tune correctly.
  • Argon2id: 2015, configurable time/memory/parallelism, current recommendation.

Tuning parameters

All three functions have parameters that trade hash time against security. A reasonable target is ~100 ms per hash on the production server, which is imperceptible during login but enormously expensive at brute-force scale. For Argon2id, OWASP recommends 19 MiB memory, 2 iterations, and 1 parallelism as a baseline. For bcrypt, cost 12+ is the floor in 2026. For scrypt, N=2^17 (~128 MB), r=8, p=1 is a common setup.

Migration strategy

If you have an existing user base hashed with bcrypt and want to move to Argon2id, the standard approach is to re-hash at login: when a user logs in successfully, you verify their password against the old hash, then immediately re-hash with the new function and update the stored record. Over a few months, most active users will be migrated transparently. For inactive users, leave the bcrypt hash in place — it's still safe.

What about pepper?

A 'pepper' is a single secret value added to all passwords before hashing, stored separately from the database (e.g., in an HSM or an environment variable). Pepper doesn't replace salt — each user still needs their own salt — but it adds defense in depth against an attacker who steals the database but not the secret store. Recommended for high-security applications.

常见问题

Should I migrate existing bcrypt hashes to Argon2id?
Not urgently. Properly-tuned bcrypt is still safe in 2026. If you have free engineering bandwidth, migrate; otherwise, focus on other security work. Migrate-on-login is the easiest path.
Is PBKDF2 still acceptable?
Acceptable, but not recommended for new systems. PBKDF2 is in many regulatory standards (FIPS, NIST SP 800-63B) so you may need it for compliance. For internal systems, prefer Argon2id.
How do I store the hash output?
Use the standard 'modular crypt format' for the chosen function. For Argon2: '$argon2id$v=19$m=19456,t=2,p=1$<salt>$<hash>'. The string contains parameters, salt, and hash together so verification can re-derive the configuration.

In summary

Use Argon2id for new systems and migrate from bcrypt opportunistically. Salt every password, target ~100 ms per hash on production hardware, and never use a general-purpose hash like SHA-256 for password storage. Generate test passwords with our Password Generator and read our Hash Functions guide for the underlying primitives.

相关工具