Free tool

htpasswd generator for Apache and Nginx

Enter usernames and passwords to get a ready .htpasswd file for HTTP basic auth, hashed with bcrypt, APR1-MD5 or SHA-1. The Apache or Nginx config and the matching htpasswd command are written for you.

Free · no sign-up · runs in your browser, nothing is uploaded

bcrypt ($2y$): the strongest option Apache supports. Nginx accepts it only where the system crypt() does.

Users

Passwords stay in this tab. Use [show] to read a random one before you copy the file; you will need it to log in.

.htpasswd

Enter a username and password. The file content appears here.

Server config
location / {
    auth_basic           "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

Same with the htpasswd command:

# Create the file with the first user (htpasswd asks for the password)
htpasswd -c -B -C 10 /etc/nginx/.htpasswd jane
# Add more users: the same command without -c
htpasswd -B -C 10 /etc/nginx/.htpasswd another_user
Check an existing line

Paste a line from an existing .htpasswd file to test a password. Works with bcrypt, APR1, {SHA}, {SSHA} and {PLAIN}.

What goes in an .htpasswd file

One user per line: the username, a colon, and the password hash. The prefix of the hash tells the server which algorithm made it. Nginx also allows comment lines starting with # and an optional third :comment field.

# Both lines are for the password "myPassword" (examples from the Apache docs)
admin:$2y$05$c4WoMPo3SXsafkva.HHa6uXQZWr7oboPiC2bT/r7q1BB8I2s0BRqC
deploy:$apr1$qHDFfhPC$nITSVHgYbDAK1Y0acGRnY0
FormatPrefixApacheNginxhtpasswd flagNotes
bcrypt$2y$YesIf the system crypt() supports it-B (cost: -C 4-17, default 5)Strongest; the docs call it very secure
APR1-MD5$apr1$YesYes-m (the default)1,000 rounds of MD5 with a salt
SHA-1{SHA}YesYes (1.3.13+)-sUnsalted; both docs call it insecure
Salted SHA-1{SSHA}NoYesnoneAlso used by OpenLDAP and Dovecot
crypt13 charactersUnix onlyVia crypt()-dUses only the first 8 characters: insecure

The username can be up to 255 bytes and cannot contain a colon. The generator checks both, flags duplicate names, and makes a new random salt for every line, so the output changes each time even for the same password. Every version verifies.

Password-protect a site with Nginx

Save the file outside the web root, point a location at it, then test and reload the config:

# /etc/nginx/sites-available/staging.conf
server {
    server_name staging.example.com;

    location / {
        auth_basic           "Staging";
        auth_basic_user_file /etc/nginx/.htpasswd;
    }

    # Leave a health check open
    location = /health {
        auth_basic off;
    }
}
sudo nginx -t && sudo systemctl reload nginx

Nginx checks $apr1$, {SHA}, {SSHA} and {PLAIN} itself and passes other hashes to the operating system's crypt(). That is why bcrypt works on some servers and not others: if logins fail with a bcrypt file, switch to APR1 or {SSHA}.

Password-protect a folder with Apache

In the virtual host, or in an .htaccess file in the folder to protect. .htaccess only works when the folder allows it with AllowOverride AuthConfig (or All).

<Directory "/var/www/html/admin">
    AuthType Basic
    AuthName "Admin area"
    AuthUserFile /etc/apache2/.htpasswd
    Require valid-user
</Directory>

Require valid-user lets in anyone listed in the file; Require user admin allows only that user. After editing the vhost, check it with apachectl configtest and reload Apache. Changes to .htaccess and to the password file apply on the next request.

The htpasswd command

htpasswd ships with Apache: install apache2-utils on Debian and Ubuntu, or httpd-tools on Fedora, RHEL and similar. You do not need Apache itself to use it.

htpasswd -c -B -C 10 /etc/nginx/.htpasswd admin   # create the file (-c truncates!)
htpasswd -B /etc/nginx/.htpasswd deploy            # add or update a user
htpasswd -v /etc/nginx/.htpasswd admin             # check a password
htpasswd -D /etc/nginx/.htpasswd deploy            # delete a user
htpasswd -nB admin                                 # print the line, do not write a file

# Without Apache tools
openssl passwd -apr1                               # prompts, prints a $apr1$ hash
docker run --rm httpd:2.4 htpasswd -nbB admin 'secret'

-b takes the password on the command line, where it is saved in your shell history and visible to other users in the process list. Prefer the prompt, or this page.

Keep basic auth safe

Basic auth sends Authorization: Basic plus the Base64 of user:password on every request (RFC 7617). Base64 is not encryption, so serve protected pages only over HTTPS. Use a long random password per person (the [random] button makes 20 characters), and remove users who leave with htpasswd -D.

For password hashing in your own app, see the bcrypt generator. To decode a captured Basic header, use the Base64 decoder. Server and deployment tools are in DevOps tools on DevHunt.

FAQ

How do I generate an htpasswd password?+

Enter a username and password above (or click [random]); the line appears in the .htpasswd box as user:hash. Copy or download it and save it as the file your server config points to. With shell access you can run htpasswd -c -B /path/to/.htpasswd username instead, which asks for the password.

Which algorithm should I use for .htpasswd?+

bcrypt for Apache: the docs call it very secure. For Nginx, bcrypt works only if the system crypt() supports it, so test a login after deploying; APR1-MD5 and {SSHA} work with Nginx everywhere because Nginx checks them itself. Avoid {SHA}: it is unsalted and both projects call it insecure.

Where should I put the .htpasswd file?+

Outside the folder the web server serves, so it can never be downloaded, for example /etc/nginx/.htpasswd or /etc/apache2/.htpasswd. The server process must be able to read it. The path in auth_basic_user_file or AuthUserFile must match where you saved it.

How do I add a user without overwriting the file?+

Run htpasswd without -c: htpasswd -B /etc/nginx/.htpasswd newuser. The -c flag creates the file and truncates it if it exists. With this page, add the new user as a row and append only their line to the existing file.

Can htpasswd passwords be decrypted?+

No, the file stores hashes, not encrypted passwords. They can only be guessed, which is why a slow hash like bcrypt matters if the file leaks. To test a password against an existing line, use "Check an existing line" above or htpasswd -v file user.

Is basic authentication secure?+

Only over HTTPS. The browser sends the username and password with every request, encoded in Base64 (RFC 7617), which anyone on the network can decode. Behind HTTPS it is a reasonable way to keep a staging site or an admin folder away from the public and from search engines.

Why does Nginx return 500 or keep asking for the password?+

A 500 usually means Nginx cannot read the file: check the path and permissions in the error log. A repeated prompt means the username or password does not match: check for a stray space or Windows line ending in the file, and that the hash format is one your Nginx supports.

Sources: Apache: htpasswd · Apache: password formats · Apache: authentication and authorization · Nginx: ngx_http_auth_basic_module · RFC 7617 (HTTP Basic auth) · RFC 2307 ({SHA} and {SSHA} schemes) · OpenSSL passwd. Checked 2026-10-30.