How do you use this tool?
- Pick the webserver — Apache or nginx. The choice sets the hash-algorithm default and disables incompatible options.
- Enter username and password. The strength meter shows entropy and heuristic warnings live.
- For bcrypt, choose the cost factor (10 / 12 / 14). The single-shot benchmark measures actual hashing latency on your device.
- Single or batch mode. Batch accepts `user:password` per line and emits a complete `.htpasswd` block.
- Copy the result or download as `.htpasswd`. Everything happens in the browser — no server, no account.
What does the htpasswd generator do?
The generator emits Apache .htpasswd lines — pure-client, so your password never leaves the
browser. You pick the webserver (Apache or nginx), enter user plus password, and the generator picks
the matching hash algorithm by default: bcrypt for Apache, APR1-MD5 for nginx. If you try an
incompatible combination (bcrypt on nginx), the warning appears immediately — not when production
already shows crypt_r() failed (22) in the error log.
Four hash algorithms are built in, chosen against the 2026 security baseline:
- bcrypt — the OWASP default, with cost factor 4 / 10 / 12 / 14 selectable. A single-shot benchmark measures the actual hashing latency on your device before you hash.
- APR1-MD5 — Apache legacy plus nginx compatibility. 1000 MD5 iterations with an 8-byte salt.
- SHA-1 —
{SHA}prefix, no salt, no stretching. Only as nginx fallback when APR1 fails; otherwise discouraged. - crypt (DES) — the original Apache default. Truncates passwords at 8 characters and falls to dictionary attacks trivially in 2026. Historic setups only.
Single mode and batch mode are separate tabs. In batch, you paste user:password lines and receive
a complete .htpasswd block — with a per-entry cost-override option. The strength meter shows
entropy and heuristic warnings (dictionary hits, common substitutions, keyboard walks) live as you
type.
What bcrypt cost factor should you use in 2026?
bcrypt is the only one of the four .htpasswd algorithms still recommended without reservation in
2026. The algorithm dates from 1999, builds on the Blowfish block cipher and uses an adaptive cost
factor — every step doubles the hashing time. That makes bcrypt future-proof: if GPU hardware
doubles in five years, you bump the cost factor by one and the security margin stays the same.
The OWASP Password Storage Cheat Sheet recommends cost 12 as the minimum for 2026. The Apache htpasswd CLI default is still cost 10 — that was fine in 2014, but it is too weak today. Cost 14 is more conservative (~1.5 s per hash) but noticeably slow for login workflows.
The generator measures actual hashing time on your device before you hash the final password. You see: “Cost 12 = 287 ms in this browser.” That lets you pick a cost factor by latency rather than gut feeling. On a slow mobile browser, cost 11 is plenty; on a modern desktop, cost 13 is often still snappy. Presets: 4 (demos), 10 (Apache CLI), 12 (OWASP), 14 (conservative).
Which algorithm fits Apache or nginx?
Apache mod_auth_basic plus mod_authn_file accept all four algorithms without complaint — the
recommended choice is bcrypt. The generator picks that automatically when you select ‘Apache’ above.
The matching .htaccess block reads:
AuthType Basic
AuthName "Protected"
AuthUserFile /path/to/.htpasswd
Require valid-user
You can build the matching block in parallel with the .htaccess generator — it ships an HTTP Basic Auth rule with realm and path fields.
nginx is different. auth_basic_user_file calls the system crypt() function and only accepts the
hashes crypt() understands: APR1-MD5 ($apr1$), SHA-1 ({SHA}), DES-crypt and plaintext (which
you should obviously never use). bcrypt is rejected — the generator’s webserver toggle disables
bcrypt automatically for nginx. If you want bcrypt verification on nginx, you need OpenResty with a
Lua module or a dedicated auth plugin — both sit outside the Basic-Auth standard directive.
Why is APR1-MD5 deprecated and how do you migrate?
APR1-MD5 plays an odd dual role: legacy on Apache, standard on nginx. The algorithm uses 1000 MD5
iterations with an 8-byte salt — adequate in 2010, crackable in under a second on 2026 GPU
hardware. New Apache installs should never reach for APR1; an existing APR1 .htpasswd should be
migrated to bcrypt line by line.
Migration steps:
- Generate new bcrypt hashes per user (use the generator’s batch mode).
- Delete the old APR1 lines from
.htpasswd, insert the new bcrypt lines. - Reload
.htaccess(Apache reload is enough, no restart needed). - Test the login once per user — Apache verifies both formats in parallel, the switch is transparent.
Migration is harder on nginx because bcrypt is rejected. Three paths: (a) keep APR1 and rotate passwords on a schedule, (b) move to OpenResty plus a Lua auth module, (c) replace Basic Auth entirely with a modern auth system (OAuth2-Proxy, Authelia, Cloudflare Access). Path (c) is the correct long-term answer for 2026 — Basic Auth was never designed as production auth.
How can you verify the password never leaves the browser?
Nobody but you sees this password. The generator has no server endpoint for hashing, no telemetry
ping, no cookie, no account. The only Web Crypto API call is crypto.getRandomValues for salt bytes
— that runs in the browser, no network call. The bcrypt algorithm is bundled as a pure-JS
implementation; APR1, SHA-1 and crypt likewise.
To verify it yourself:
- Open the tool, open DevTools (F12).
- Switch to the ‘Network’ tab, filter on ‘All’.
- Enter a password, generate the hash.
- The network tab shows zero requests during hashing — no POST, no WebSocket, nothing.
The form element has no action attribute, the inputs carry autocomplete=\"new-password\" so your
browser doesn’t cache the plaintext in form history. Close the tab and the password is gone — the
generator persists nothing in localStorage or sessionStorage. If you want an audit, the source
code is on GitHub and the lint blocks any fetch call in this tool path.
How does the batch mode help DevOps and team setups?
Batch mode solves the DevOps team-setup scenario: ten developers need access to a staging
environment, each with their own password. You paste ten user:password lines into the batch
field, pick algorithm plus cost factor, and you receive a complete .htpasswd file — one hash per
line, ready to upload to the server.
The strength meter runs per entry so you can immediately spot weak passwords. Optional: per-entry
cost override — admin accounts get cost 14, service accounts cost 12. The download button hands you
the file in the right format. Combined with the .htaccess generator, you
can build a complete HTTP Basic Auth configuration in two tab switches — .htaccess plus
.htpasswd, both pure-client.
What is intentionally not built?
- No password suggestions — password generation belongs in the dedicated password generator, not in a hash emitter. Mixing both functions would cost trust (‘does the generator see my password?’ FAQ).
- No hash cracking — the generator emits, it does not break. To recover a lost hash, use John the Ripper or hashcat locally; no browser tool can do this in reasonable time.
- No SSO / OAuth integration — HTTP Basic Auth is its own auth scheme. For modern auth use an
OIDC provider, not
.htpasswd. The generator serves the classic Basic-Auth use case exactly. - No Argon2 variant — Apache
htpasswddoes not support Argon2. If you need Argon2, configure a dedicated auth module or move to application-layer auth.
Where can I read more?
- Apache htpasswd manual 2.4 — official CLI documentation
- OWASP Password Storage Cheat Sheet — hash algorithm recommendations 2026
- nginx Issue #1154 — the official bcrypt rejection with reasoning
- OpenSSL 3.0 manual — cryptographic primitives behind bcrypt/APR1
- bcrypt on Wikipedia — history, algorithm, cost-factor math
- MD5 on Wikipedia — why MD5 (and therefore APR1) is unsafe in 2026
Last updated: