Htpasswd generator for Apache and Nginx
This htpasswd generator converts plain username:password pairs into the hashed lines that Apache's mod_auth_basic and Nginx's auth_basic_user_file expect. It does the same job as the htpasswd command-line utility, which is handy when you are on a machine without apache2-utils installed or need entries for several users at once.
What is an .htpasswd file?
An .htpasswd file is a plain text list with one user per line: the username, a colon, and a password hash. The web server reads it when a protected location is requested, hashes the password the visitor typed, and compares. The file never needs to contain the real password, only a hash in a format the server recognizes.
Example
With the tool's sample input and the default bcrypt option at cost 10, you get one line per user:
admin:$2y$10$prK.TZ9TxuKtfHcAnM5R9uhdBgNTMMIMMfBP7HLt6Gk3A0vLALJzS
alice:$2y$10$rY.0TmwbvWR4VI4qCTSqrujyjUhMynYUNlCT48u0fAeSSzf08hKGm
Because every hash gets a fresh random salt, running the tool again produces different output for the same password. Both versions verify correctly. The same password with the other two algorithms looks like this:
admin:$apr1$dOwYH/tZ$6Ctd2kG2teqmAbLWJWBWo.
admin:{SHA}iEYguQJFGKubtHRfunjGIVgU2P0=
Hash options explained
| Option | Prefix | Notes |
|---|---|---|
| bcrypt (recommended) | $2y$ | Slow, salted, tunable cost. Supported by Apache 2.4+ and by Nginx on systems whose crypt() library understands bcrypt, such as distributions built on libxcrypt. |
| Apache MD5 (apr1) | $apr1$ | Salted MD5 with 1,000 rounds. Works on every Apache and Nginx version, but it is fast to brute force by current standards. |
| SHA-1 {SHA} (legacy) | {SHA} | Unsalted SHA-1 in Base64. Identical passwords give identical hashes. Only use it for old systems that accept nothing else. |
The bcrypt cost is a base-2 logarithm: each step doubles the work. Cost 10 is a reasonable default for basic auth because the server hashes the password on every request. Going to 12 or higher makes each protected page load noticeably slower.
Using the output
For Apache, point AuthUserFile at the file inside a <Directory> block or .htaccess, with AuthType Basic and Require valid-user. For Nginx, add auth_basic "Restricted"; and auth_basic_user_file /etc/nginx/.htpasswd; to the server or location block. Keep the file outside the web root and readable only by the server user.
Basic authentication sends the credentials Base64-encoded with every request, so always serve protected areas over HTTPS. You can see exactly what the browser sends with the Basic Auth header generator.
Common errors and fixes
- Nginx always returns 401 with bcrypt – Nginx relies on the operating system's crypt() function, and some older distributions ship one without bcrypt. Use apr1 on those systems.
- "must look like username:password" – each line needs a colon. Passwords may contain colons, because only the first colon splits the line, but usernames cannot contain spaces or colons.
- Long passwords – bcrypt only uses the first 72 bytes of a password. A longer passphrase still works, but characters beyond that limit do not add strength.
- Windows line endings – if you edit the file on Windows, save it with LF endings; a trailing carriage return can break the last field.
Need a strong password first? Create one with the password generator, or hash a single value with the dedicated bcrypt generator.
Privacy
All hashing happens in your browser, and salts come from crypto.getRandomValues. The usernames and passwords you type are never uploaded.