Skip to content
T
Tools.Town
Free Online Tools for Everyone
Security

How .htpasswd and HTTP Basic Auth Really Work

A practical guide to HTTP Basic Auth: what a .htpasswd file is, how APR1, SHA-1, and bcrypt hashing differ, and how to protect a directory on Apache or Nginx safely.

24 June 2026 4 min read By Tools.Town Team Fact Checked

Key Takeaways

  • It's secure enough to gate a staging site, an admin folder, or an internal tool, provided you serve it strictly over HTTPS so the credentials are encrypted in transit
  • Use APR1 for maximum portability, or bcrypt (generated server-side with htpasswd -B) for the strongest hashing

The simplest lock on the web

Long before single sign-on and OAuth, the web had a built-in way to put a username-and-password prompt in front of any directory: HTTP Basic Authentication. It’s still everywhere, because it’s trivial to set up and needs no database, no session store, and no application code. If you’ve ever hit a browser pop-up asking for a username and password before a page even loaded, that was Basic Auth.

The whole system rests on one small file — .htpasswd — and a couple of lines of server configuration. This guide explains what that file contains, how the hashing works, and how to wire it up safely. If you just want the file, the HTPasswd Generator produces a correct entry in seconds; read on to understand what it’s giving you.

What a .htpasswd file actually contains

A .htpasswd file is plain text. Each line is one user, in the form:

username:hash

The username is stored as-is. The password is never stored directly (unless you choose the insecure plain-text option). Instead, the server stores a one-way hash. When someone types a password, the server hashes what they typed and compares it to the stored hash. If they match, access is granted. Because the hash can’t be reversed, someone who steals the file still can’t read the passwords — they’d have to brute-force each one.

A real file with two users looks like this:

admin:$apr1$Xx9zKq0P$RN.e5frAuuSafq5/PUW2A1
deploy:{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=

The first user uses APR1; the second uses SHA-1. The prefix ($apr1$ or {SHA}) tells the server which algorithm to use when checking a password. The HTPasswd Generator builds exactly these lines for you.

The three hashing formats

APR1 — Apache’s portable MD5

APR1 is the format produced by htpasswd -m, and it’s the most portable choice. It’s a salted, iterated MD5 scheme designed by the Apache team. The $apr1$ prefix is followed by a random salt, then the hash. The salt is the key to its safety: because each entry uses a different random salt, two users with the same password get completely different hashes, which defeats precomputed “rainbow table” attacks. APR1 runs 1,000 rounds of MD5 mixing, which slows down brute-force attempts. It isn’t the strongest scheme by modern standards, but it works identically on Linux, macOS, and Windows, which is why it remains the safe default.

SHA-1 — the {SHA} format

The {SHA} format is base64-encoded SHA-1 of the password, produced by htpasswd -s. Crucially, it is unsalted, so identical passwords always produce identical hashes — a real weakness. It exists mostly for compatibility with older systems and LDAP. Prefer APR1 or bcrypt over SHA-1 for anything new.

bcrypt — the strongest, but server-side

bcrypt (htpasswd -B, prefix $2y$) is the gold standard for password hashing. It’s deliberately slow and has a tunable “cost factor” so you can make it slower as hardware improves. The catch is that a correct bcrypt implementation is heavy, which is why the HTPasswd Generator doesn’t try to do it in the browser — it focuses on portable APR1 and recommends you generate bcrypt entries with the real htpasswd binary when you need maximum strength. If you want to understand why slow hashing matters, the trade-offs are the same ones that make a strong password valuable in the first place.

Wiring it up on Apache

Once you have a .htpasswd file, point Apache at it. In your site config or an .htaccess file in the directory you want to protect:

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

AuthName is the text the browser shows in the prompt. AuthUserFile must be an absolute path, and it should sit outside your web root so it can never be downloaded. Reload Apache and the directory is protected.

Wiring it up on Nginx

Nginx reads the same file format with two directives inside a location or server block:

location /staging/ {
  auth_basic "Restricted Area";
  auth_basic_user_file /etc/nginx/.htpasswd;
}

That’s it — the same .htpasswd file works for both servers, which is one more reason the portable APR1 format is convenient.

Security do’s and don’ts

A few rules turn Basic Auth from “better than nothing” into “genuinely useful”:

  • Always use HTTPS. Basic Auth sends the username and password (base64-encoded, not encrypted) on every request. Over plain HTTP, anyone on the network can read them. Over HTTPS, they’re protected.
  • Keep the file out of the web root. If .htpasswd is reachable by URL, attackers can download it and brute-force the hashes offline.
  • Use a strong password. Hashing only buys time; a weak password falls quickly to a dictionary attack. Generate one with the Password Generator and follow the principles in our strong password guide.
  • Prefer APR1 or bcrypt. Never ship plain text. Treat SHA-1 as legacy-only.
  • One file, many users. Add a line per user; remove a line to revoke access instantly.

When to reach for something bigger

Basic Auth has real limits. There’s no logout button (browsers cache the credentials until they’re closed), no password-reset flow, no per-user permissions beyond “in the file or not,” and no protection against credential stuffing beyond the hash’s own slowness. The moment you need accounts, roles, or self-service password changes, it’s time for a proper authentication system.

But for what it does — putting a quick, reliable gate in front of a directory with zero application code — Basic Auth is hard to beat. Generate a correct entry with the HTPasswd Generator, drop it in place, and your staging site or admin folder is locked down in under a minute.

Troubleshooting common errors

When Basic Auth doesn’t work, the cause is almost always one of a handful of small mistakes. If the browser keeps re-prompting even with the right password, the stored hash probably doesn’t match — regenerate the entry and paste it carefully, making sure no stray space crept in around the colon. If you get a 500 Internal Server Error on Apache, the AuthUserFile path is likely wrong or unreadable by the web-server user; double-check it’s an absolute path and that the file’s permissions let the server read it. On Nginx, a 403 usually means the auth_basic_user_file directive points at a missing file. And if the prompt never appears at all, confirm the module is enabled (mod_auth_basic on Apache) and that your config block actually covers the URL you’re testing.

Two subtler issues catch people out. First, whitespace in the file: each line must be exactly username:hash with nothing trailing. Second, caching: browsers hold onto Basic Auth credentials for the life of the tab, so after changing a password you may need to open a fresh private window to see the new prompt rather than the cached old credentials.

A quick reference

To recap the decision in one place: choose APR1 for a portable entry that works everywhere, bcrypt (via htpasswd -B) when the content is sensitive and your server supports it, and never plain text outside a throwaway local test. Always pair the file with HTTPS, keep it outside the web root, and use a strong, generated password. Follow those rules and a one-line file gives you reliable, server-level protection with effectively zero maintenance.

Advertisement

Try HTPasswd Generator — Free

Apply what you just learned with our free tool. No sign-up required.

Try HTPasswd Generator

Frequently Asked Questions

Is HTTP Basic Auth secure enough for production?
It's secure enough to gate a staging site, an admin folder, or an internal tool, provided you serve it strictly over HTTPS so the credentials are encrypted in transit. It is not a replacement for a real authentication system with sessions, password reset, and account lockout — but for a quick, server-level gate it's perfectly reasonable.
What's the difference between .htpasswd and .htaccess?
.htaccess is an Apache configuration file that can turn on Basic Auth and point at a user file. .htpasswd is that user file — it stores the username:hash pairs. Nginx doesn't use .htaccess at all, but it reads the same .htpasswd format via auth_basic_user_file.
Which hashing algorithm should I pick?
Use APR1 for maximum portability, or bcrypt (generated server-side with htpasswd -B) for the strongest hashing. Avoid plain text entirely, and treat SHA-1 as legacy. The right choice depends on what your server supports and how sensitive the protected content is.

Was this guide helpful?

Your feedback helps us improve our content.

Continue Reading

All Security Guides

Get the best Security tips & guides in your inbox

Join 25,000+ users who get our weekly security insights.