Subscribe

Cryptography

Password hashing libraries that store a verifier, not a souvenir (2026)

A 2026 shortlist of password hash APIs. Public docs, not a cracking lab.

Expertise: Cryptography · Level: Intermediate · 12 min read

MD5 of the password is not a program.

The TLS list is the library you link on the wire. This page is the verifier you store. Overlap is none and the failure is still a leaked table. I will not publish a crack recipe.

Six APIs. One Argon2 binding. Two bcrypts. One sodium. One compatibility shelf. One language button. Public docs. Not a bake-off.

Technical check: we cross-check first-party product pages, public licenses, and live documentation. Rank is a technical recommendation, not a recap of other lists, and not a lab bake-off.

ToolBest forLicense
argon2-cffiArgon2id in Python you can actually callMIT
bcryptKnown slow hash when Argon2 is not on the boxApache-2.0
libsodiumcrypto_pwhash in the library you may already linkISC
Go x/crypto/bcryptbcrypt in a Go service you ownBSD-3-Clause
passlibVerify yesterday’s hashes while you migrateBSD-3-Clause
PHP password_hashThe language button on PHPPHP License
Where it sits
Argon2 / sodium
Language API
bcrypt
Compat shelf
1

argon2-cffi

Best for argon2id in Python you can actually call

The Python binding people import. Argon2id is the OWASP-shaped default if you still store a password.

Key features

  • Argon2id helper
  • MIT
  • You set memory and time
  • Well kept

Why we like it

This is the hidden gem for a Django or Flask app that still has a password column.

Limits

You pick parameters. A low memory cost is theater. Not a passkey.

2

bcrypt

Best for known slow hash when Argon2 is not on the box

pyca bcrypt. Work factor you can name. Still acceptable when the runtime cannot do Argon2.

Key features

  • Work factor
  • Apache-2.0
  • Wide install base
  • You store the hash

Why we like it

Honest fallback. Do not invent a homemade iterate-SHA.

Limits

Memory-hard it is not. Tune the cost as hardware moves.

3

libsodium

Best for crypto_pwhash in the library you may already link

libsodium password hashing is Argon2-based in current docs. Same library as the boxed crypto you wanted anyway.

Key features

  • crypto_pwhash
  • ISC
  • Many language bindings
  • You pick opslimit

Why we like it

When sodium is already a dependency, do not add a third hash crate for fashion.

Limits

Bindings differ. Read the current primitive name. Not a user database.

4

Go x/crypto/bcrypt

Best for bcrypt in a Go service you own

The import a Go login actually uses. Cost parameter. Compare is the API. Do not roll your own constant-time.

Key features

  • GenerateFromPassword
  • CompareHashAndPassword
  • BSD-3-Clause
  • Stdlib-adjacent

Why we like it

A Go app does not need a Python binding. Call this.

Limits

bcrypt limits. Cost is yours. Argon2 in Go is a different module if you need it.

5

passlib

Best for verify yesterday’s hashes while you migrate

passlib is a hash menagerie. Useful when the table is a mix of leftover schemes. The end state should still be Argon2id or bcrypt.

Key features

  • Many schemes
  • Context migrate helpers
  • Docs on deprecation
  • You still pick a default

Why we like it

A migration without a compatibility shelf stalls. Then someone copies plaintext.

Limits

Unmaintained stretches exist. Do not add a weak scheme ‘just in case.’

6

PHP password_hash

Best for the language button on PHP

password_hash and password_verify. Default follows PHP’s current PASSWORD_DEFAULT. Do not store a raw MD5 next to it.

Key features

  • Language built-in
  • password_needs_rehash
  • Current default documented
  • No extra package

Why we like it

Honesty. A PHP app that still calls md5() is the hole this row exists to close.

Limits

Read what DEFAULT is this year. Rehash on login. Not a passkey.

What the internet thinks about password hashing

Hash threads treat homemade SHA loops as the smell. We agree. This page will not publish a cracking lab.

Prove argon2-cffi still publishes

Confirm argon2-cffi still publishes. Hash a test password in a scratch project you own. Do not attack a stolen table.

git ls-remote --heads https://github.com/hynek/argon2-cffi.git

FAQs

Argon2 or bcrypt?

Argon2id if you can. bcrypt if that is what the runtime already does well. Name the cost.

Should I encrypt the hash too?

A pepper can help a stolen table. It is not a substitute for a slow KDF.

Do passkeys retire this list?

For those users, yes. Until then you still store a verifier. Link passkey tools.

Is this a scored bake-off?

No.