Password Security
Passwords are still the most common way to prove identity. The core rule is that an application should never be able to read a user's password back, only check whether a guess matches.
Hash, do not store or encrypt
- Plain text means anyone who reads the database sees every password.
- Encryption is reversible. If the key is stolen along with the data, or the application can decrypt, so can an attacker.
- Hashing is one-way. You store the hash of the password, and at login you hash the submitted value and compare. There is nothing to decrypt.
A general-purpose hash such as plain SHA-256 is the wrong tool, because it is designed to be fast and attackers can test billions of guesses per second. Use a password hashing algorithm built to be slow and memory-hungry: Argon2id is the usual first choice, with scrypt, bcrypt and PBKDF2 as established alternatives. Take parameters from current guidance such as the OWASP cheat sheet; do not guess them.
Salts
A salt is a random value stored with each hash and mixed into it. Every user gets a different salt, so identical passwords produce different hashes and attackers cannot use precomputed tables. Modern password hashing libraries generate and store the salt for you. Use the library’s functions and do not build your own scheme.
Handling passwords in applications
- Never log passwords, send them in URLs or include them in error messages.
- Always transmit them over HTTPS (see TLS and HTTPS Basics).
- Allow long passwords and passphrases and do not forbid pasting, so password managers work. Length matters more than odd character rules.
- Reject known-breached and very common passwords.
- Rate-limit login attempts and offer multi-factor authentication (MFA).
- Support a safe reset flow instead of ever emailing existing passwords.
- Where possible, delegate login to an established identity provider (see Authentication vs Authorization).
For your own accounts
Use a password manager with a unique password for every service, and turn on MFA, especially for source control, cloud and email accounts. Treat a password that appeared in a breach as burned everywhere it was used.
Try it
Using a language of your choice, hash the same password twice with a library such as bcrypt or Argon2 and compare the two outputs. Why are they different, and how can the library still verify a login? Then find out how your own team’s application stores passwords.
Common mistakes
- Using a fast hash such as plain SHA-256 for passwords.
- Building your own salting or hashing scheme.
- Logging passwords or sending them in URLs.
- Blocking paste or long passwords, which breaks password managers.
Check yourself
- Why is hashing better than encryption for stored passwords?
- Why is plain SHA-256 the wrong choice?
- How can a library verify a login when the same password gives different hashes?