What goes into the .htpasswd line
An .htpasswd file holds one entry per line in the form username:hash. Apache's mod_auth_basic and nginx's auth_basic_user_file both read it. This page builds the line for you in one of two schemes, and refuses a username that is empty or contains a colon, because the colon is the field separator.
| Scheme | Looks like | Salted? | Verdict |
|---|---|---|---|
| bcrypt | admin:$2y$10$xp1/FLEY... (60-character hash) | Yes, 16 random bytes per hash | Use this |
| SHA-1 | admin:{SHA}5en6G6MezRroT3XKqkdPOmY/BfQ= | No | Legacy compatibility only |
How bcrypt and its cost setting work
A bcrypt hash has four parts: the version marker ($2y$), the cost (10), a 22-character salt, and a 31-character hash. The cost is a power of two: bcrypt performs 2 to the power of cost rounds of its key setup, so each +1 doubles the time. The page offers 8 to 12, with 10 as the default. In a Node.js test on a normal computer, the times were about 14 ms at cost 8, 56 ms at 10 and 228 ms at 12; browser speeds will differ, but the doubling pattern is the same. Since the salt is random, the same password produces a different line each time you press Generate, and all of them are valid.
The library, bcryptjs, writes the prefix $2b$. The page rewrites it to $2y$, the marker that Apache's own htpasswd -B writes, and the two verify identically. bcrypt support needs Apache 2.4 (recent releases of the 2.4 series); older 2.2 servers cannot read it. nginx passes the hash to the operating system's crypt(), so bcrypt works only if the platform's C library supports it. Check this on your server before relying on it.
Worked example
For user admin and password secret, the SHA-1 scheme gives admin:{SHA}5en6G6MezRroT3XKqkdPOmY/BfQ=: the SHA-1 digest of the password, Base64 encoded. It is identical every time, which is exactly the weakness: two users with the same password have the same hash, and precomputed tables exist for common passwords. The bcrypt scheme returns a fresh 60-character hash on each click.
Details that catch people out
- The password box is masked. Characters are hidden while you type, and a Show/Hide button next to the box reveals them so you can check for typos. Nothing is sent anywhere; the hash is computed in your browser.
- bcrypt only reads the first 72 bytes of a password. Two passwords that share their first 72 bytes produce hashes that both verify with either.
- Apache's default MD5 format (
$apr1$) is not offered. If you need it, use the command-linehtpasswdtool. - Basic authentication is not encrypted. The browser sends the password with only Base64 encoding, so serve protected areas over HTTPS; the hash only protects the file on the server.
- Multiple users: generate each line separately and put them on separate lines of the same file, then point
AuthUserFileto it, outside the web root.
To compare general-purpose digests see the hash generator, to pick a strong password use the password generator, and for server config files see the redirect generator.