Hashing Passwords in 2026: Argon2, bcrypt, and What Not to Use

By Λ · May 18, 2026 · 8 min read

If your application stores passwords, you do not store passwords. You store hashes. That much is uncontroversial. What is still surprisingly controversial in 2026 is which hash function to use, what parameters to set, and what categories of "still in production" code should be replaced today.

This is the field guide I wish I could hand to every junior engineer who has just been told "we use SHA-256 with a salt, why is that bad?" It is also a useful reference for senior engineers who have not revisited the topic since the OWASP guidance shifted.

Important framing. The advice below is for password storage on a server. It does not apply to file integrity hashes, content-addressable storage, message authentication codes, or any other "I need a digest of this data" scenario. Those use different algorithms for different reasons.

The three properties that matter

A good password hash function has three properties beyond standard cryptographic hash properties:

  1. Salt support. A unique random salt per password defeats precomputed rainbow tables. This has been settled since the 1970s; if your hash function does not accept a salt, do not use it.
  2. Tunable cost. The hash should be expensive to compute, with a cost parameter you can increase as hardware improves. SHA-256 takes nanoseconds; a password hash should take 100 to 500 milliseconds on commodity hardware.
  3. Memory-hardness. An attacker building specialized hardware (GPUs, FPGAs, ASICs) gets a smaller speedup against memory-hard algorithms than CPU-only ones. Argon2 and scrypt are memory-hard; bcrypt and PBKDF2 are not.

The 2026 ranking

Use: Argon2id

Argon2 won the Password Hashing Competition in 2015. The "id" variant combines protections against GPU attacks (Argon2d) with protections against side-channel attacks (Argon2i). OWASP recommends Argon2id as the default choice for new applications. Most modern languages have a maintained Argon2 library.

Recommended parameters for 2026 (interactive web logins):

These produce a hash in about 100 ms on a modest cloud VM, which is the sweet spot for login latency. Bump the memory cost first when hardware improves; it scales attacker cost without hurting user experience much.

Acceptable: bcrypt (with cost >= 12)

bcrypt has been around since 1999 and is in production at huge scale. It is not memory-hard, which means a well-resourced attacker with GPUs gets a meaningful speedup compared to Argon2id. But for most applications, bcrypt at cost 12 or higher remains a defensible choice.

The reason to keep bcrypt on the acceptable list in 2026 is operational: rotating an entire user database from bcrypt to Argon2id is a meaningful project, and the security gain is moderate. If you already use bcrypt and are happy with cost 12+, leaving it in place is fine. If you are starting fresh, use Argon2id.

Acceptable: scrypt (with N >= 32768)

scrypt was the first widely-deployed memory-hard hash. It is now older than Argon2 and less actively developed, but the underlying algorithm is still solid. If you have an existing scrypt deployment with adequate parameters, you do not need to migrate. For new code, Argon2id is the cleaner choice.

Acceptable, with caveats: PBKDF2 (with iterations >= 600,000)

PBKDF2 is in the NIST standard library and required in some compliance regimes. It is not memory-hard, so attackers with custom hardware get a big speedup. Use it only when an explicit regulatory requirement forces your hand, and pair it with HMAC-SHA-256 or HMAC-SHA-512 (never HMAC-SHA-1).

Do not use, even with a salt

What to do with old hashes

Common scenario: your app uses bcrypt cost 8 (set up when bcrypt cost 8 felt slow). You want to upgrade. The path that works in production:

  1. Pick the target: Argon2id at the parameters above, or bcrypt cost 12.
  2. When a user logs in and provides their password, verify against the existing hash. If verification succeeds, recompute with the target algorithm and overwrite the stored hash. The user does not notice.
  3. For users who do not log in often, do nothing. They will be migrated on their next login.
  4. After a year (or whatever window covers your active user base), audit the remaining old hashes and decide whether to force a password reset on those users.

This pattern works because the new hash uses the same underlying password the user just typed. You never need the plaintext of the old hashes.

Peppers and other "extra security" patterns

A "pepper" is a site-wide secret value that you append to the password before hashing, stored outside the database. The theory is that an attacker who dumps the database still cannot crack the hashes without the pepper. The practice is mixed: peppers are useful but operationally annoying (key rotation, key management, key disaster recovery).

OWASP's current guidance: peppers are valuable for high-value deployments (financial, healthcare, defense). For most consumer applications, a strong primary hash function with appropriate parameters is the higher-leverage investment.

Where the hash generator on this site fits in

The hash generator on BoltQuickTools is explicitly NOT a password storage tool. It produces single-pass digests (MD5, SHA-1, SHA-256, SHA-384, SHA-512) for file integrity checks, deduplication keys, and content addressing. Do not store passwords with it. If you need password hashing in an application, use Argon2id via a maintained library in your language.

I built the hash generator for the common developer task of "I have a file and I want to verify its checksum against the one the publisher posted." That is a legitimate use of fast hashes. Password storage is not.

Quick reference checklist

Related