ITInfoByte

Htpasswd Generator & Checker

Enter usernames and passwords to build a complete .htpasswd file for HTTP basic authentication, then copy it or download it. Hashing happens on this page with random salts from your browser's secure generator. The checker tells you whether a password matches a line you already have.

On-device — downloads its library once Security Free · no signup
Network notice: Your usernames and passwords never leave your device. For bcrypt, the open-source bcrypt.js library (Apache 2.0 license) is fetched from the cdnjs CDN the first time you use it; APR1-MD5 and SHA-1 need no download.

How to use

  1. Choose the hash type. bcrypt is the default and the one to use unless your server cannot read it; APR1-MD5 is the fallback for older setups.
  2. For bcrypt, pick a cost. Each step up doubles the work for an attacker and for your server on every login; 10 is a reasonable default.
  3. Enter a username and password. Click Random to fill in a strong 20-character password, and Add user for more rows.
  4. Click Generate to hash every row. Each hash gets a fresh random salt, so running it twice gives different but equally valid lines.
  5. Copy the result or download the file (saved as htpasswd, because browsers will not save a name starting with a dot). Upload it to your server outside the web root, rename it to .htpasswd if you like, and point AuthUserFile (Apache) or auth_basic_user_file (Nginx) at it.
  6. To test an existing entry, paste the line into Check a password, type the password and click Check.

Examples

bcrypt, cost 5 (salt is random each time)
admin:$2y$05$2GnMsGt1s1jxC1Q8wT93veR4T75qP9W2djV7WUnyPl5am3JA5ZI72
APR1-MD5, password "password", salt abcdefgh
admin:$apr1$abcdefgh$FBwExRW4dCc8aL.OvjpIE1
SHA-1, password "password" (legacy, unsalted)
admin:{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=
Apache: .htaccess or <Directory> block
AuthType Basic
AuthName "Restricted"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
Nginx: server or location block
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;

Supported formats

  • bcrypt: $2y$ hashes in the same form as htpasswd -B, cost 5 to 14. Apache 2.4.4 and later read them.
  • APR1-MD5: $apr1$ hashes with an 8-character salt, as made by htpasswd -m and openssl passwd -apr1. Apache and Nginx both read them.
  • SHA-1: {SHA} followed by the Base64 SHA-1 digest, as made by htpasswd -s. Unsalted and fast to crack, so offered only for legacy systems.
  • Output: one user:hash line per user with a trailing newline, ready to save as .htpasswd (the download is named htpasswd; any file name works). The checker accepts a full user:hash line or just the hash.

Privacy

Your input is processed in your browser and is never uploaded. The first time you use the tool, your browser downloads its open-source processing library from cdnjs.cloudflare.com — the library is downloaded, your data is not sent. Privacy policy.

Limitations

  • Nginx checks $apr1$ and {SHA} itself, but passes any other hash, including bcrypt, to the operating system's crypt() function. So bcrypt works only if that crypt() understands $2y$. Many current Linux distributions support it, but older or minimal systems may not. Test one login before you rely on it, or use APR1-MD5 for Nginx.
  • crypt() formats (DES, $1$, $5$ and $6$) and plain-text passwords are not generated or checked here.
  • bcrypt only uses the first 72 bytes of a password. Longer passwords still work, but the extra characters are ignored, and the page warns you when that happens. Accented and non-Latin characters take 2 to 4 bytes each in UTF-8.
  • bcrypt is deliberately slow, and this page computes it in JavaScript, so a high cost (13 or 14) can take several seconds per user.
  • The tool builds a new file. It does not edit or merge an existing .htpasswd, but you can paste the new lines into one. Remove any old line for the same username, because the server uses the first match.

FAQ

Which hash should I choose?

bcrypt, if your server supports it. It has a random salt and a cost you can raise, so stolen hashes are slow to crack. APR1-MD5 is salted but fast, so it is much weaker against offline guessing; use it when bcrypt is not available, such as on Nginx where the system crypt() lacks bcrypt. Avoid SHA-1: it has no salt, so identical passwords give identical hashes, and it can be guessed very quickly.

Why does the hash start with $2y$ and not $2a$ or $2b$?

$2y$ is what Apache's htpasswd -B writes. For ordinary passwords, $2a$, $2b$ and $2y$ give the same hash for the same password and salt; the letters record which implementation fixed which old bug. The library used here computes the current, corrected algorithm and the page writes the $2y$ label to match htpasswd, so the line is what Apache expects. The checker accepts all three prefixes.

Are my passwords sent anywhere?

No. The hashes are computed in your browser: bcrypt with the bcrypt.js library, APR1-MD5 with code on this page, and SHA-1 with the Web Crypto API. Salts come from crypto.getRandomValues(). For bcrypt, the page downloads the library from cdnjs; your passwords are not sent.

Why does generating the same password twice give a different line?

bcrypt and APR1 add a random salt to every hash, so the same password gives a different hash each time. Both lines are valid. The salt is stored in the hash, so the server can still check the password. SHA-1 has no salt, so its output is always the same.

Where should I put the .htpasswd file?

Outside the directory your site is served from, so it cannot be downloaded, for example /etc/apache2/.htpasswd or /etc/nginx/.htpasswd. Make it readable by the web server user, and serve the protected area over HTTPS: basic auth sends the password with every request, encoded but not encrypted.