Why a slow hash
When a database leaks, attackers guess passwords offline against the stored hashes. A fast hash such as SHA-256 lets a single GPU try about ten billion guesses per second, which turns most human-chosen passwords into plaintext within hours. Password hashing functions are deliberately slow and, in the newer designs, memory-hungry, so that each guess costs the attacker as much as it costs you, and a GPU's thousands of cores do not help because they share too little memory.
| Function | Year | Tunable | Recommended (OWASP 2024) | Use when |
|---|---|---|---|---|
| Argon2id | 2015 | memory, passes, lanes | m=19 MiB, t=2, p=1 (or m=64 MiB, t=3) | Default for new systems. Winner of the Password Hashing Competition. |
| scrypt | 2009 | N, r, p | N=2¹⁷, r=8, p=1 | Memory-hard; fine where Argon2 is unavailable. |
| bcrypt | 1999 | cost (2ⁿ rounds) | cost 10 or more | Everywhere; still solid. Truncates at 72 bytes. |
| PBKDF2 | 2000 | iterations | 600,000 (SHA-256) | FIPS compliance; not memory-hard, so weakest against GPUs. |
Reading a hash string
$2b$12$ + 22 characters of salt + 31 of hash: bcrypt, cost 12 (4,096 rounds). $argon2id$v=19$m=19456,t=2,p=1$salt$hash: Argon2id with its parameters in the string, Base64 without padding. Both formats carry everything needed to verify, so you can raise the cost over time and rehash users at their next login. scrypt and PBKDF2 have no universal string format; the salt and parameters are stored alongside, which is why the verifier asks for the salt separately.
Picking a cost
Aim for roughly 100–300 ms per hash on your server. This page reports how long each hash took in your browser (a decent laptop is comparable to a small server core). Argon2 at the recommended 19 MiB takes about a second in JavaScript; native implementations are several times faster.
What not to do
Do not use MD5, SHA-1 or SHA-256 alone, even salted. Do not use a single site-wide salt. Do not pre-hash with SHA-256 to get around bcrypt's 72-byte limit unless you also Base64 the result (raw bytes can contain NUL, which bcrypt stops at). And do not paste real production passwords into any web page, including this one; use test values.
Questions
Is it safe to use this page with a real password?
The hashing runs in your browser and nothing is transmitted, but the sensible rule is to treat every web page as untrusted for live credentials. Use it to generate hashes for test fixtures, to understand formats, and to verify with throw-away passwords.
Why does bcrypt give a different hash each time?
The salt is random on every call; it is stored inside the hash string. Verification extracts it and recomputes. Two hashes of the same password are expected to differ; both verify.
Why does my bcrypt verification fail for a long password?
bcrypt uses only the first 72 bytes. If the password was hashed by a library that pre-hashes (some Django and Passlib configurations), the raw bcrypt verification here will not match. Also check the prefix: $2y$ and $2b$ hashes are compatible; $2x$ marks a buggy implementation.
What do m, t and p mean in Argon2?
m is memory in KiB (19456 = 19 MiB), t is the number of passes over that memory, p is the number of lanes that can run in parallel. Memory is the main security knob: it is what makes GPU and ASIC attacks expensive.