Htpasswd Generator→Specialized Version
πŸ”’

Apache htpasswd Generator

Generate Apache .htpasswd entries

Salted and iterated 1000 times. Portable across every platform Apache runs on and the default for `htpasswd -m`.

Hashing runs in this tab and nothing is uploaded β€” but generate credentials you intend to use with htpasswd on the server rather than in a browser.

Apache configuration
<Directory "/var/www/private">
    AuthType Basic
    AuthName "Restricted Area"
    AuthUserFile /etc/apache2/.htpasswd
    Require valid-user
</Directory>

A .htaccess file is ignored unless AllowOverride permits it, so a directory can appear unprotected with no error. Keep .htpasswd outside the document root.

bcrypt is not offered here. It needs a native implementation that browsers do not provide. If your Apache supports it, htpasswd -B -c .htpasswd user is the stronger choice β€” APR1 is the portable fallback, not the best one.

APR1 Is Apache's Own Format

The $apr1$ prefix marks Apache's variant of MD5-crypt: a salted, iterated MD5 designed in the 1990s to be slow enough to resist the hardware of the time. It is what htpasswd produces by default and what every Apache installation reads without configuration.

An entry is one line:

`` username:$apr1$SALT$HASHEDPASSWORD `

Protecting a Directory

`apache AuthType Basic AuthName "Restricted Area" AuthUserFile /etc/apache2/.htpasswd Require valid-user `

Three things go wrong most often:

1. The .htpasswd file is inside the web root, where it can be downloaded. Put it outside, or deny access to it explicitly. 2. AllowOverride is not set, so a .htaccess file is ignored entirely and the directory is not protected at all. Test with a private browser window before assuming. 3. The path is relative. AuthUserFile needs an absolute path.

APR1 Is Not a Modern Password Hash

Iterated MD5 is fast on modern hardware, which is exactly what a password hash must not be. A GPU rig tries billions of MD5 operations a second, so an APR1 hash of a weak password falls quickly.

Use it where it belongs: gating a staging site, a metrics dashboard, an internal tool β€” with a long random password, over HTTPS, and with no expectation that the hash file could survive being leaked. For real user accounts use bcrypt, scrypt or Argon2 in your application.

Basic Auth Sends Credentials Every Request

HTTP Basic transmits base64(user:password) in a header on every single request. Base64 is encoding, not encryption β€” anyone who can read the traffic can read the password. Over HTTPS that is acceptable; over HTTP it is a plaintext password on the wire, repeatedly.

Generated in Your Browser

The salt comes from crypto.getRandomValues() and the hash is computed locally. The password never leaves your machine, which is the whole reason not to use an online generator that posts it to a server.

Testing It Works

`bash # Should return 401 curl -I https://staging.example.com/

# Should return 200 curl -I -u admin:password https://staging.example.com/

# What the browser actually sends printf 'admin:password' | base64 # YWRtaW46cGFzc3dvcmQ= β†’ Authorization: Basic YWRtaW46cGFzc3dvcmQ= `

That last line is the whole security model: base64, no key, reversible by anyone who sees the header. Over TLS it is fine; over plain HTTP it is equivalent to publishing the password.

Keeping Machines Out but Letting the Right Ones In

A blanket auth gate breaks things you rely on. Exempt them explicitly:

PathWhy
/.well-known/acme-challenge/Let's Encrypt renewal fails otherwise, silently, until the certificate expires
/healthzLoad balancer and uptime probes
/api/webhooks/Third-party callbacks cannot authenticate

Blocking Crawlers Properly

Basic auth keeps a staging site out of search results, and it is worth pairing with the other two signals so that nothing leaks through a link:

` # robots.txt User-agent: * Disallow: / `

` X-Robots-Tag: noindex, nofollow `

Note that robots.txt alone does not prevent indexing β€” it prevents crawling, and a URL linked from elsewhere can still appear in results without a snippet. The noindex header is what actually removes it.

CI and Scripts

`bash # curl curl -u "$STAGING_USER:$STAGING_PASS" https://staging.example.com/

# Playwright await context.setHTTPCredentials({ username, password }); ``

Keep the credentials in secrets, never in the repository β€” a password committed to git stays in the history after you delete it.

Frequently Asked Questions

What does the $apr1$ prefix mean?

It identifies Apache’s MD5-crypt variant. The line is `$apr1$` followed by an eight-character salt, another `$`, and the hash. Apache reads the prefix to know which algorithm to verify with, so it must be preserved exactly.

Where should the .htpasswd file live?

Outside the document root β€” `/etc/apache2/.htpasswd` rather than `/var/www/html/.htpasswd`. A password file inside the web root can be requested over HTTP and downloaded, which hands an attacker every hash in it.

Is Basic Auth secure enough?

Over HTTPS, for gating a staging site or internal tool, yes. It sends the credentials on every request, has no session, no lockout and no logout, so it is not suitable for real user accounts β€” and over plain HTTP it is a plaintext password on the wire.

Related Tools

Explore other tools you might find useful:

More Htpasswd Generator tools

You might also need