Skip to content
ZeroServer.tools

.htpasswd Generator

Generate Apache .htpasswd entries for basic authentication using bcrypt or SHA-1.

Bcrypt (cost 10) is the recommended choice for modern Apache installations.

.htpasswd File Generator

Apache HTTP Server uses .htpasswd files to store credentials for basic authentication. Each line contains a username and a hashed password. Bcrypt is the most secure option and is supported by Apache 2.4+. SHA-1 is faster but less secure and is retained for compatibility with older setups. All hashing runs entirely in your browser — your password never leaves your device.

Built and maintained by Meet Shah · Last updated

What this tool is used for

  • Putting a staging site behind a credential prompt without adding an application-level login.
  • Adding a second factor of obscurity in front of an admin path on an Apache host.
  • Producing an entry to append to an existing password file for one more user.
  • Rotating a shared credential for a directory that several people access.
  • Protecting a directory on shared hosting where you only control the config files.

How it works in practice

A worked example

A staging site needs a password prompt for one outside reviewer, so the developer generates an .htpasswd line for the user reviewer, presses Generate a second time with bcrypt, then tries the SHA-1 option for comparison.

Input
Username   reviewer
Password   lantern-harbour-27
Algorithm  bcrypt (recommended), the default; Generate pressed twice
           then SHA-1; Generate pressed once
Output
bcrypt, 1st press   reviewer:$2y$10$lgasElEi8DMCENwY9maBxO3SDIMRNiNeUR6L/UkaVieri/zfbHsSC
bcrypt, 2nd press   reviewer:$2y$10$JFxn4ZBd96F40mMXlZdd6eSRilFpoS.KV3AWHk0apGKnIcxiyAzXS
SHA-1               reviewer:{SHA}AWIQ4T4P0PKaw02COZUX51K1QkY=

Each line is a username, a colon, then the stored hash, and Apache's file provider splits the line at its first colon. In the bcrypt lines, $2y$ marks bcrypt and 10 is the cost: bcrypt re-keys its cipher with the password and the salt 2^10, or 1,024, times. The next 22 characters are the salt and the last 31 are the hash. The salt is drawn fresh on every press, which is why the two presses differ even though both match the same password; an independent C implementation of bcrypt reproduced both hashes from the password and rejected a wrong one. These lines come from one real session, so your bcrypt lines will differ, but the SHA-1 line will match exactly. It is the Base64 of a single unsalted digest, the same on every press and for anyone who picks the same password, and Apache's own documentation lists that format as insecure.

The edge case that catches people

bcryptjs, the library behind this page, writes its hashes with a $2b$ prefix, and the page relabels it $2y$ before showing the line. The relabelling matters because APR, the library Apache uses to check passwords, treats only $2a$ and $2y$ as bcrypt and hands a hash it does not recognise, $2b$ included, to the system crypt(). On builds with no crypt(), Windows among them, APR then compares the typed password with the stored text as plain text, so a correct password never matches a $2b$ line. A $2b$ hash copied from another bcrypt tool therefore works only where the system crypt() happens to support that prefix, while the $2y$ lines from this page go through APR's own bcrypt code on every platform.

When not to use this tool

The cost is fixed at 10, while htpasswd -B defaults to 5, and each step of cost doubles the work, so every check here is 32 times as expensive. Apache pays that on every request that carries the credentials, including each image and stylesheet under the protected path, and mod_authn_socache does not avoid it, because it caches the stored hash and still runs the full comparison. In one measurement, a C bcrypt took about 50 ms per check at cost 10 and under 2 ms at cost 5. For a protected area that serves many files, create the entry with htpasswd -B and a -C cost measured on your own server instead.

Frequently Asked Questions

Which hash format should I pick?
bcrypt ($2y$), supported by Apache 2.4 and the only option here designed to resist offline cracking. MD5-crypt ($apr1$) is the historical default and is weak by modern standards; plain crypt() truncates at 8 characters.
Where must the password file live?
Outside the document root. If it sits in a web-accessible directory, anyone can download every hash — which turns an access-control measure into a credential leak. The .htaccess file references it by absolute path.
Is Basic Auth safe over plain HTTP?
No. Credentials are Base64-encoded — not encrypted — and are resent on every request, so anyone on the network path can read them. It is only acceptable over HTTPS, where TLS protects the header.
What is the difference from Digest authentication?
Digest never sends the password itself, hashing a challenge instead, so it was designed for unencrypted links. It is now largely obsolete: it forces weaker password storage server-side, and HTTPS solved the problem better.
How do users log out?
There is no logout in HTTP Basic Auth — browsers cache credentials for the session. Access is revoked by removing the user's line from the file, which Apache picks up on the next request with no restart needed.
Why is bcrypt preferred over the older formats here?
Because the alternatives are weak by modern standards: crypt truncates at eight characters, and plain MD5 or SHA-1 entries are fast enough to brute-force offline if the file leaks. Apache's bcrypt support has a work factor, which is the point.
Can I protect a single file rather than a directory?
Yes, with a <Files> or <FilesMatch> block around the auth directives. Directory-level protection is the common case, but a per-file rule is what you want for a single admin endpoint sitting among public pages.
Can a username contain a colon?
No. Apache splits each line at its first colon, so dev:ops would be read as the user dev with ops as its stored hash. No password matches that on Unix, while Windows builds, which compare an unknown hash as plain text, would let dev in with ops. The page refuses it, as htpasswd does.

Common errors and gotchas

  • Leaving the password file inside the web root, where it can be fetched directly unless you have blocked it explicitly.
  • Using Basic auth over plain HTTP, which sends the credential in a trivially decodable header on every request.
  • Choosing an older hash format because it is shorter, when bcrypt is available and far more resistant to cracking.
  • Expecting a logout. Basic auth has no logout, and the browser will keep resending the credential until it is closed.
  • Starting a username with #, which Apache's file provider reads as a comment line, so that user can never sign in.

Related Generators tools

Private & free — this tool runs entirely in your browser.

Bluehost — Reliable WordPress & web hosting — exclusive pricing from $3.79/mo.affiliate