Storing a password as SHA256(password) feels secure — it's a well-known cryptographic hash function — but it's precisely the wrong tool for the job, for one specific reason: speed.
Why generic hash functions fail here
SHA-256 is designed to be fast, because most of its use cases (checksums, digital signatures) benefit from speed. That same speed is a liability for passwords: if an attacker steals your password hash database, a fast hash function lets them attempt billions of guesses per second on cheap GPU hardware.
What password hashing functions actually do differently
Purpose-built password hashing functions (bcrypt, scrypt, Argon2) are deliberately slow and tunable, so you can increase the computational cost as hardware gets faster over time.
- bcrypt — widely deployed, well-understood, tunable via a work factor.
- scrypt — additionally memory-hard, making GPU/ASIC-based cracking more expensive.
- Argon2 (specifically Argon2id) — the current recommended default from most standards bodies, combining resistance to both time-based and memory-based cracking optimizations.
Salting is not optional
Every password hash needs a unique, random salt, stored alongside the hash. Without it, identical passwords produce identical hashes, making precomputed rainbow-table attacks trivial across your entire user base at once.
Choosing parameters
Password hashing functions expose tunable cost parameters (work factor for bcrypt, memory/iterations for Argon2). The right value increases over time as hardware improves — a work factor considered strong five years ago may be comparatively weak today. Periodically re-evaluate and increase parameters, migrating existing hashes on next successful login rather than requiring a mass password reset.
Never roll your own
Implementing your own password hashing scheme, even using strong primitives, introduces subtle mistakes (timing attacks, incorrect salt handling) that well-reviewed libraries have already solved. Use a maintained, audited library for your language rather than assembling one from cryptographic primitives yourself.
Password storage is one of the few areas where "use the standard, well-reviewed approach" is unambiguously the right answer — there's little upside to customization here.