Storing passwords safely

Password storage has one goal: keep user passwords protected even if the application database is copied by an attacker. That means never storing plaintext passwords, never using r…

Password storage has one goal: keep user passwords protected even if the application database is copied by an attacker. That means never storing plaintext passwords, never using reversible encryption for normal login passwords, and never relying on fast hashes.

Store password verifiers, not passwords

A login system does not need to know the user's password after registration. It only needs to verify that a later attempt matches the original secret.

The safe pattern is to run the password through a password hashing algorithm and store the resulting verifier. On login, run the submitted password through the same algorithm and compare the result.

The stored value should include the algorithm and parameters needed for verification. That makes future migration possible without forcing every user to reset their password at once.

Use a password hashing algorithm

Use a dedicated password hashing algorithm, not a general purpose hash.

Argon2id is a strong default when it is available. OWASP also documents scrypt, bcrypt and PBKDF2 as options when they fit the platform or compliance requirement. Bcrypt is best reserved for legacy systems, and it silently truncates input beyond 72 bytes, so enforce that limit if you use it.

The important property is cost. Password hashing should be deliberately expensive enough to slow large scale guessing, while still acceptable for normal login traffic. General purpose hashes such as SHA-256 are too fast for password storage.

Use a unique salt for every password

Each password must have a unique salt. The salt prevents attackers from using one precomputed table against every account and stops equal passwords from producing equal stored values.

The salt is not secret. It should be generated with a cryptographically secure random source and stored with the password verifier. Most modern password hashing libraries generate and embed the salt for you.

Do not use a single application wide salt. That gives weaker protection than per password salts and creates a shared value that can become a migration problem.

Consider a pepper only as defence in depth

A pepper is an additional secret value used alongside the password hashing process. Unlike a salt, a pepper must be kept secret and stored away from the password database, ideally in a secrets vault or hardware security module.

A pepper can reduce damage if only the database is stolen. It does not replace strong password hashing, unique salts or secure implementation. If the pepper is exposed, plan to rotate it and reset affected password verifiers.

Validate without leaking information

The registration and reset flows should help users choose strong passwords without exposing account state or sensitive implementation details.

Use generous minimum length requirements that support passphrases, and allow long inputs of at least 64 characters. Do not impose outdated complexity rules that push users towards predictable substitutions. Screen new passwords against known compromised password lists where practical.

Avoid login and reset responses that reveal whether an account exists. Rate limit authentication attempts and protect password reset flows with short lived, single use tokens.

Migrate old hashes safely

Old password storage schemes should be upgraded. The usual approach is lazy migration: when a user logs in successfully, verify the old hash, then rehash the submitted password with the current algorithm and parameters.

Use an explicit version marker for each stored verifier. That avoids guessing how a value was produced and lets the application know which accounts still need migration.

Force resets only when needed, such as after a confirmed leak, an unsafe legacy format that cannot be verified safely, or a compromised pepper.

Operational controls matter

Password storage is not only an algorithm choice. Restrict database access, protect backups, monitor unusual authentication activity and keep authentication libraries patched.

Do not log plaintext passwords, password reset tokens or password hash values. Redact authentication inputs in application logs and telemetry.

Treat authentication code as high risk code. Keep it small, tested and reviewed.

Conclusion

Safe password storage uses slow, dedicated password hashing with a unique salt per password and current parameters. Encryption, fast hashing and custom schemes are the wrong tools. Design the surrounding flows so passwords, reset tokens and verifiers do not leak through logs, backups or account recovery.