Skip to main content

BCrypt hash generator

The recommended .htpasswd format, in 3 clicks

Want to add an account to a .htpasswd file with the recommended algorithm, without installing apache2-utils? Enter a username and a password: the $2y$ line is ready to paste.

The cost is an exponent: every step doubles the computation time. 10 is what htpasswd -B uses, 12 is a sound trade-off today.

Key features

Native $2y$ format

The bcrypt hashing of htpasswd -B, derived from Blowfish. Works with Apache 2.4, nginx, Traefik and Caddy.

Adjustable cost factor

From 4 to 15, on a slider. Every step doubles the work demanded of an attacker. Defaults to 10, like htpasswd -B.

Line ready to paste

The result is shown as a complete user:hash line, copyable straight into your .htpasswd file.

Fresh salt on every call

A 128-bit salt is embedded in the hash by bcrypt. Two accounts sharing a password get two different hashes.

Nothing is kept

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

Why generate a bcrypt hash online?

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

Since Apache 2.4, htpasswd -B produces bcrypt, and that is the format the official documentation recommends. The catch: that command assumes you installed apache2-utils on Debian or httpd-tools on RHEL. On a Windows machine, on shared hosting or from a web panel, it is often missing.

Three situations where this generator helps:

  • Protect a staging environment → Close access to a test site 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
  • Modernise an existing file → Gradually replace $apr1$ entries with $2y$ ones

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 your input before submitting. The "Generate a password" button draws a random 16-character string if you do not have one yet.

Step 2: Set the cost factor

The slider starts at 10, the htpasswd -B value. Raise it to 12 for sensitive access. Every step doubles the computation time: at generation, and at every check the server performs.

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 your server configuration.


Anatomy of a bcrypt hash

A .htpasswd line splits into two fields separated by a colon:

admin:$2y$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy

The second field breaks down like this:

PartExampleRole
Algorithm identifier2yTells the server this is bcrypt
Cost factor10Exponent: the computation runs 2^10 = 1,024 rounds
Salt + digestN9qo8uLOickgx2ZMRZoMye...53 characters: 22 for the 128-bit salt, 31 for the digest

Unlike APR1-MD5, the salt does not sit in its own field: it is glued to the digest in the last block. It stays readable in plaintext, which is expected - its job is not to be secret, but to stop a precomputed table from recovering the password.


Understanding the cost factor

The cost is an exponent, not a multiplier. A cost of N runs 2^N key-derivation rounds:

CostRoundsIndicative timeUse
8256~15 msToo weak today
101,024~60 mshtpasswd -B default, fine
124,096~250 msRecommended for sensitive access
1416,384~1 sNoticeable latency on every login

Two things to keep in mind. First, that time is paid on every check, so on every HTTP Basic request: a cost of 14 on a page whose browser replays authentication for each asset is felt immediately. Second, the right setting depends on your hardware: measure rather than copy a number, the usual target being 100 to 250 ms on the server that will run the check.


Protecting a directory with Apache

1. Create the file

Put your .htpasswd file outside the web root, so it is never 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 this way:

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

nginx reads bcrypt from version 1.0.3 onwards on systems whose crypt_r() supports it, which covers every common Linux distribution.


bcrypt against the other .htpasswd formats

FormatPrefixComputation costVerdict
bcrypt$2y$Adjustable, 2^cost roundsRecommended for any new project
APR1-MD5$apr1$1,000 MD5 iterationsAcceptable, maximum compatibility
SHA-1{SHA}1 iteration, no saltAvoid: no salt, breakable by table
crypt() DESnone25 iterations, truncated to 8 charactersObsolete, stop using it

In short: bcrypt is the only .htpasswd format whose cost adjusts to the hardware of the day. The other three have a fixed cost, decided in the 1990s or 2000s, that GPU progress has made trivial. Keep APR1-MD5 only if your server cannot read $2y$.


Verifying the hash from the command line

This tool returns a standard bcrypt hash, verifiable with system utilities:

# Generate the equivalent with htpasswd (apache2-utils / httpd-tools package)
htpasswd -nbB admin myPassword

# Force a cost factor of 12
htpasswd -nbB -C 12 admin myPassword

The two strings will not be identical - the salt differs on every draw - but both validate the same password. To check that:

# Replay the verification using the salt of an existing hash
python3 -c "import bcrypt,sys; print(bcrypt.checkpw(b'myPassword', sys.argv[1].encode()))" '$2y$10$...'

FAQ - Frequently asked questions

Q: What is the $2y$ format?

A: It is the bcrypt marker inside a .htpasswd file. A full hash follows the pattern $2y$<cost>$<salt><digest>: an algorithm identifier, a two-digit cost factor, then 53 characters holding the 128-bit salt and the digest. That is what htpasswd -B writes.


Q: What is the difference between $2a$, $2b$ and $2y$?

A: None that matters, they are three markers for the same algorithm. $2y$ was introduced by PHP in 2011 to flag an implementation fixed for a non-ASCII character bug, a bug absent from the library used here. Apache and nginx accept all three.


Q: Which cost factor should I pick?

A: 10 by default, 12 for sensitive access. The right reflex is to measure on the server that will run the check and aim for 100 to 250 ms: slow enough to hamper a dictionary attack, fast enough to go unnoticed in daily use.


Q: Why can I not go past 15?

A: Since the cost is an exponent, 16 already demands several seconds of computation and would outlast the budget of an HTTP request. For a higher cost, generate the hash locally with htpasswd -B -C 18.


Q: Is bcrypt better than APR1-MD5?

A: Yes, clearly. APR1-MD5 chains 1,000 MD5 iterations, which specialised hardware computes by the billion every second. bcrypt demands memory and non-sequential access, which severely limits a GPU's parallelism. For a new .htpasswd file, bcrypt without hesitation.


Q: Can I use a password longer than 72 characters?

A: No, and that is not a limit of this tool: bcrypt simply ignores anything past 72 bytes. An 80-character password would therefore be equivalent to its first 72. Careful, an accented character counts as two bytes in UTF-8.


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: 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 - which is precisely what the cost factor makes expensive, though not impossible.


ToolPurpose
APR1-MD5 generatorProduce a .htpasswd line in the historical Apache format
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

Useful resources


Privacy commitment

Your password is sent to the CaptainDNS API solely to compute the hash, over an encrypted connection. It is never stored or logged. Only anonymous technical metrics are kept (processing time, response code).