SHA-256, for the jobs that suit it.
Checksums, signatures, content addressing and integrity checks. SHA-256 is the sensible default for all of them. It is the wrong tool for passwords, and the reason is the same speed that makes it good at everything else.
Everything here runs locally
The hash updates as you type. There is no button to press.
Why a fast hash fails at passwords
Say somebody walks off with your users table. If the passwords sit there as SHA-256 digests, the attacker starts working through a list of common passwords, hashing each one and comparing. A single graphics card manages billions of those per second.
Adding a salt to each row stops them testing one guess against every account at once, and it makes precomputed tables useless. It does not slow down a single guess at all. That is the part only a deliberately slow function fixes.
- SHA-256, unsalted
- Billions of guesses per second, and every common password is already in a public lookup table.
- SHA-256 with a salt
- Still billions of guesses per second, but the attacker has to do it once per account.
- PBKDF2-SHA256, 600k iterations
- The same hash function, made expensive by repeating it. Thousands of guesses per second instead of billions.
- bcrypt at cost 12
- A few guesses per second per core, and awkward enough that graphics cards do not help much.
If SHA-256 is what your environment allows, the middle path is PBKDF2. It is the same function, run enough times to matter.
The same digest elsewhere
Worth knowing if you are comparing this page's output against something on your own machine. Watch for trailing newlines, which is the usual reason two hashes of the same text disagree.
# macOS and Linux, no trailing newline
printf '%s' 'hello' | shasum -a 256
# a file
sha256sum ./archive.tar.gz
# Node
node -e "console.log(require('crypto').createHash('sha256').update('hello').digest('hex'))"
# Python
python3 -c "import hashlib; print(hashlib.sha256(b'hello').hexdigest())"