How (not) to hash a password

Last updated: September 28, 2026

The most widespread mistake: storing SHA-256(password). It is fast… for you and for the attacker alike. Here is why, and what to do instead.

The problem: fast hashes are too fast

SHA-256 is designed to be very fast. A graphics card computes billions of them per second. If your password database leaks, an attacker tests every common word and every short combination in no time (see brute force). A fast hash slows nobody down.

The solution: slow, salted functions

Functions dedicated to passwords are deliberately slow and configurable: you choose a cost that makes every attempt expensive. They also include a salt.

  • bcrypt: proven, adjustable cost;
  • Argon2id: recommended today, memory-hard;
  • scrypt: memory-hard;
  • PBKDF2: long-standing standard, very widespread.

Salt: against precomputed tables

The salt is a random value, different for each password, added before hashing. Two people with the same password get different hashes. Above all, the salt makesprecomputed tables (rainbow tables) useless: the attacker can no longer reuse work done in advance. The salt is not secret; it is stored with the hash (the bcrypt/Argon2 formats include it).

Pepper: a server-side secret

The pepper is a global secret, the same for everyone, but keptoutside the database (in the server configuration, a hardware module…). That way, a leak of the database alone is not enough: without the pepper, the hashes hold up. Salt and pepper are complementary.

In short

  • Never a plain SHA-256/MD5 for a password.
  • A slow, salted function: preferably Argon2id, otherwise bcrypt/scrypt.
  • A unique salt per password (handled automatically by these functions).
  • Optionally a pepper, kept separately.