Skip to main content
Comparisons

bcrypt vs Argon2 vs scrypt vs PBKDF2: Which Password Hash to Use

By Byteary Team · Sep 9, 2026 · 3 min read

bcrypt vs Argon2 vs scrypt vs PBKDF2: Which Password Hash to Use

Passwords must never be stored as plain text, and never with a fast hash such as MD5 or SHA-256 either. A modern graphics card can try billions of SHA-256 guesses per second. Password hashing algorithms are deliberately slow - and some deliberately memory-hungry - so that each guess is expensive. There are four worth knowing, and the choice between them is simpler than it looks.

What makes a password hash different

All four algorithms share three properties that a plain hash lacks:

  • A salt: a random value stored with each hash, so two users with the same password get different hashes and precomputed tables are useless.
  • A work factor: a setting that makes hashing slower, which you raise as hardware gets faster.
  • A self-describing output: the algorithm, parameters and salt are stored in the hash string, so you can verify old hashes after changing the settings.

The four algorithms side by side

Argon2idscryptbcryptPBKDF2
Year2015 (won the Password Hashing Competition)200919992000
Memory-hardYes, tunableYesNo (small fixed memory)No
Resists GPU/ASIC crackingBestGoodModerateWeakest
Main settingsMemory, iterations, parallelismN, r, pCost (log2 rounds)Iterations, hash function
OWASP minimum19 MiB memory, 2 iterations, 1 threadN=217, r=8, p=1Cost 10600,000 iterations (HMAC-SHA-256)
Input limitNone in practiceNone in practice72 bytesNone in practice
FIPS-140 approvedNoNoNoYes

The parameters come from the OWASP Password Storage Cheat Sheet, which is the best single reference on this topic.

Byteary Argon2id Hash Generator with 19456 KB memory, 2 iterations and parallelism 1 producing an argon2id hash string
An Argon2id hash with OWASP's minimum settings. The parameters and salt are stored inside the hash string.

Notes on each

Argon2id is the current recommendation. Because it needs a configurable amount of memory per guess, attackers cannot simply run thousands of guesses in parallel on a GPU. Use the id variant, which combines resistance to side-channel and GPU attacks. Try it with the Argon2id Hash Generator.

scrypt was the first widely used memory-hard function and is still a good choice where Argon2 is not available. Its three parameters are less intuitive. See the scrypt Hash Generator.

bcrypt has 25 years of real-world use and is the default in many frameworks. It is not memory-hard, but with a cost of 10 or more it remains acceptable. Its one real limit: only the first 72 bytes of the password are used - longer passwords are silently truncated, and some libraries now reject them instead. Try the bcrypt Hash Generator.

PBKDF2 is the weakest against GPU cracking, because it needs almost no memory, so it needs a very high iteration count. Its advantage is compliance: it is the one on this list approved for FIPS-140 environments. See the PBKDF2 Hash Generator.

Verdict

  • New application: Argon2id, at least 19 MiB memory and 2 iterations - more if your servers can afford it.
  • Existing bcrypt: keep it with cost 10-12; it is still safe. Migrate gradually if you want to.
  • FIPS-140 required: PBKDF2-HMAC-SHA-256 with 600,000+ iterations.
  • Never: MD5, SHA-1 or SHA-256 on their own, or anything you designed yourself.

In practice: use your framework's default

You rarely call these algorithms directly. Laravel's Hash::make(), PHP's password_hash(), Django's password hashers and ASP.NET Identity already handle salts, formats and upgrading. Use them, and tune the cost. To migrate, re-hash each user's password with the new algorithm the next time they log in successfully - PHP's password_needs_rehash() and Django do this for you. Byteary's Laravel, Django and PHP hash generators produce hashes in each framework's exact format, which is handy for seeding a test user.

Hashing protects stored passwords; it does not make weak passwords strong. See how to create a strong password for the other half of the story.

Comments (0)

Leave a Comment

CAPTCHA image - enter the characters shown

Your comment will appear after it's been reviewed.

Related Posts