Password Hashing
Field: Security · Also called: password hashing function, password hashing scheme, slow hash, key stretching
Password hashing is the storage of a password as the output of a deliberately expensive one-way function, combined with a unique salt, so the password itself is never stored and every guess an attacker makes is costly to test.
Why a general-purpose hash is not enough
Using a general-purpose hash function such as SHA-256 directly on a password is unsuitable for several reasons, not only speed:
- It is fast. General-purpose hashes are designed for high throughput, which lets an attacker who has the stored hashes test candidate passwords at a very high rate offline.
- It has no built-in salt. A raw hash function takes only its input bytes, so salting is left to the developer. When the salt is omitted or shared across the whole site, identical passwords produce identical hashes; see Salt.
- It has no cost factor. There is no parameter to make each computation more expensive as hardware improves.
- It is not memory-hard. It can be computed cheaply in massive parallel on GPUs and specialized hardware.
Password hashing schemes address these by design. They take a salt as a required input, usually generating it and storing it inside the output string, and they expose a tunable cost.
SHA-2 remains acceptable as a building block inside an approved construction. PBKDF2 with HMAC-SHA-256 is specified in NIST SP 800-132 and is the usual choice where FIPS 140 validation is required. The problem is using a raw hash function by itself.
Common password hashing functions
- Argon2 (RFC 9106, 2021): memory-hard. OWASP’s Password Storage Cheat Sheet lists Argon2id as its first choice.
- scrypt (RFC 7914, 2016): memory-hard, OWASP’s second choice.
- bcrypt (Provos and Mazières, 1999): built on an intentionally expensive Blowfish key schedule with an adjustable cost. Most implementations use only the first 72 bytes of input, and OWASP recommends enforcing a 72-byte maximum.
- PBKDF2 (NIST SP 800-132): iterated HMAC, recommended by OWASP when FIPS 140 compliance is required.
NIST guidance
NIST SP 800-63B (Revision 4, 2025), section 3.1.1.2, states that the salt “SHALL be at least 32 bits in length,” that an approved password hashing scheme from SP 800-132 or updated NIST guidance “SHOULD be used,” and that the cost factor “SHOULD be as high as practical without negatively impacting verifier performance” and “SHOULD be increased over time.” The same section recommends an additional keyed hashing or encryption step with a secret key stored separately, the control commonly called a pepper.
History
Provos and Mazières presented bcrypt at the 1999 USENIX Annual Technical Conference, arguing that the cost of a secure password scheme must increase as hardware improves.
In October 2024, Okta disclosed an authentication bypass in its AD/LDAP delegated authentication. It had used bcrypt to generate a cache key from the user ID, username, and password combined. With a username of 52 or more characters, the password fell past bcrypt’s 72-byte limit and was ignored. Okta replaced bcrypt with PBKDF2 for that purpose.
Sources
- NIST SP 800-63B-4, Digital Identity Guidelines: Authentication and Authenticator Management, NIST, August 2025. Retrieved October 2, 2026.
- Password Storage Cheat Sheet, OWASP Cheat Sheet Series. Retrieved October 2, 2026.
- SP 800-132, Recommendation for Password-Based Key Derivation, NIST. Retrieved October 2, 2026.
- RFC 9106, Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications, IRTF, 2021. Retrieved October 2, 2026.
- RFC 7914, The scrypt Password-Based Key Derivation Function, RFC Editor, August 2016. Retrieved October 2, 2026.
- A Future-Adaptable Password Scheme, Provos and Mazières, USENIX Annual Technical Conference, 1999. Retrieved October 2, 2026.
- Okta's 'secure by design' pledge suffers a buggy setback, CSO Online, November 2024. Retrieved October 2, 2026.
See also
Go deeper
Articles
- Bad Password Practices are Responsible For Most Data Breaches. You Can do Better. May 10, 2016
- What is the difference between bcrypt and SHA256? February 5, 2016
- Really Bad Passwords (with Unsalted Hashes) June 8, 2012
- Web Application Security & Performance September 22, 2009