Skip to main content

APR1-MD5 Hash Generator

Password-protect an Apache directory or file in 3 clicks

Need to add an account to a .htpasswd file but have no htpasswd command at hand? Enter a username and your own password: the $apr1$ line comes back ready to paste. No password yet? A button next to the field can generate one, but that is optional.

Enter the name of the account to create in the .htpasswd file.

Key features

Native $apr1$ format

Apache's salted MD5, with its 1,000 iterations and its own base64 encoding. Works with Apache, nginx and Traefik.

Secure random salt

An 8-character salt drawn from a cryptographic generator on every call. Two accounts sharing a password get two different hashes.

Ready-to-paste line

The result is shown as a complete user:hash line you can drop straight into your .htpasswd file.

Custom salt

Supply your own salt to reproduce an existing hash and compare two entries of the same file.

Nothing is kept

The password is used for the computation and then discarded. No database record, no plaintext password in any log.

Why generate an APR1-MD5 hash online?

HTTP Basic authentication is still the fastest way to close off an admin area, a staging site or an internal dashboard. It relies on a .htpasswd file where every line maps a username to a hashed password - never to a plaintext one.

The catch: producing that hash normally requires the htpasswd command, which means the apache2-utils package on Debian or httpd-tools on RHEL. On a Windows workstation, on shared hosting or from a web console, that command is often missing.

Three situations where this generator helps:

  • Lock down a staging site → Close off a preview environment before Google indexes it
  • Add an account without SSH access → Build the line in your browser and paste it through your host's file manager
  • Migrate a configuration → Rebuild a lost .htpasswd file from the credentials you still know

How to use the generator in 3 steps

Step 1: Enter the username and password

Type the account name, then its password. The field is masked by default; click the eye icon to re-read what you typed before submitting.

Step 2: Let the salt be generated

In almost every case, leave the salt field empty: a random 8-character salt is drawn server-side. Only fill it in to reproduce an existing hash byte for byte.

Step 3: Copy the line

Two results are shown: the hash on its own, and the complete .htpasswd line. Copy the latter, paste it into your file, then reload the server configuration.


Anatomy of a .htpasswd line

A line splits into two fields separated by a colon:

admin:$apr1$Xq7nD2mR$5CqLZ.k1qLkOvVQ0uZ9Yl.

The second field itself splits into three parts delimited by $:

PartExampleRole
Algorithm identifierapr1Tells the server this is Apache's salted MD5
SaltXq7nD2mR8 random characters, stored in clear in the file
Digest5CqLZ.k1qLkOvVQ0uZ9Yl.22 characters, the output of the 1,000 iterations

The salt is not a secret: it is readable in the file. Its job is to stop a pre-computed table (a rainbow table) from recovering the password, and to guarantee that two accounts sharing a password do not share a digest.


What the $apr1$ algorithm actually does

APR1-MD5 is not a plain md5(password + salt). It chains:

  1. Two initial digests - one over password + $apr1$ + salt, the other over password + salt + password
  2. A length-dependent mix - fragments of the second digest are folded back into the first, byte by byte
  3. 1,000 iterations - on each round, password, salt and previous digest are recombined following a pattern that depends on the round number
  4. A crypt base64 encoding - the final 16 bytes are read back in an interleaved order, then encoded over the ./0-9A-Za-z alphabet

Those 1,000 iterations are what separates it from a bare MD5: they multiply the cost of a single guess by a thousand, which slows a dictionary attack down by the same factor.


Protecting a directory with Apache

1. Create the file

Put your .htpasswd file outside the web root, so that it can never be served over HTTP:

/var/www/secrets/.htpasswd

2. Declare the protection

In the .htaccess of the directory to protect, or in the <Directory> block of your VirtualHost:

AuthType Basic
AuthName "Restricted area"
AuthUserFile /var/www/secrets/.htpasswd
Require valid-user

3. Reload the configuration

sudo apachectl configtest && sudo systemctl reload apache2

For nginx, the same pair of files is declared like this:

location /admin/ {
    auth_basic           "Restricted area";
    auth_basic_user_file /var/www/secrets/.htpasswd;
}

APR1-MD5 versus the other .htpasswd formats

FormatPrefixComputation costVerdict
bcrypt$2y$Tunable (cost factor)Recommended for any new project
APR1-MD5$apr1$1,000 MD5 iterationsAcceptable, maximum compatibility
SHA-1{SHA}1 iteration, unsaltedAvoid: no salt, breakable by table lookup
crypt() DESnone25 iterations, truncated at 8 charactersObsolete, do not use

In short: if your server accepts bcrypt (htpasswd -B), use it. APR1-MD5 is the best remaining option when bcrypt is unavailable - and it is vastly better than an unsalted {SHA}.


Verifying the hash on the command line

Given the same salt, this tool returns exactly what the system utilities return:

# With htpasswd (apache2-utils / httpd-tools package)
htpasswd -nbm admin myPassword

# With OpenSSL, forcing the salt
openssl passwd -apr1 -salt Xq7nD2mR myPassword

The second example doubles as a check on this tool: enter the same salt in the form and you should get exactly the same string back.

To verify that a password matches an existing line, read the salt out of the stored hash and replay the computation with that salt.


FAQ - Frequently asked questions

Q: What is the $apr1$ format?

A: It is Apache's historical password format, also called APR1-MD5. It runs 1,000 MD5 iterations over the password and an 8-character salt, then encodes the result in the crypt base64 alphabet. The $apr1$ prefix acts as the algorithm identifier.


Q: Is APR1-MD5 still safe?

A: It is far stronger than a bare MD5, but it stays cheap to compute for an attacker with GPUs. For a new project, prefer bcrypt through htpasswd -B. APR1-MD5 keeps its value where compatibility comes first: older Apache versions, nginx without bcrypt support, network appliances.


Q: Does this hash work with nginx?

A: Yes. The nginx ngx_http_auth_basic_module reads the Apache format, $apr1$ included. The generated line works as-is with auth_basic_user_file.


Q: Why do I get a different hash every time?

A: A new random salt is drawn on every generation. Both hashes are valid for the same password: on verification, the server reads the salt stored inside the hash and redoes the computation. Fill in the salt field if you want a reproducible result.


Q: Is the password stored anywhere?

A: No. It travels over HTTPS to the CaptainDNS API for the duration of the computation, then it is discarded. No database, no log holding the plaintext password.


Q: Can I use accented characters or symbols?

A: Yes, the computation runs over the UTF-8 bytes of the password. One caveat: an old HTTP client may encode non-ASCII characters differently, which would make authentication fail. When in doubt, stay in ASCII.


Q: Where should the .htpasswd file live?

A: Outside the web root, for instance in /var/www/secrets/. If it sits in a directory served over HTTP, a visitor could download it and attack the hashes offline.


ToolWhat it does
Password generatorDraw a strong password before hashing it
Hash generatorCompute MD5, SHA-1, SHA-256 and SHA-512 of a text
Base64 encoderEncode the Authorization header of a Basic request
HTTP headers viewerCheck the headers returned by a protected area
HSTS testMake sure protected access really runs over HTTPS

Useful resources


Privacy commitment

Your password is sent to the CaptainDNS API for the sole purpose of computing the hash, over an encrypted connection. It is neither stored nor logged. Only anonymous technical metrics are kept (processing time, response code).