How Handle Htpasswd in NGINX

By default nginx server does not come with htpasswd, but we can generate a password file with an external tool :)

Type of cryptography in htpasswd

htpasswd has multiple password protection methods as shown in the table below, except for bcrypt and SHA512 base, rest it is insecure.

Bcrypt is up to 72 characters, nginx basic authentication depends on system crypt.3 and it depends on the system whether it supports bcrypt.

There is also a patch that supports bcrypt by nginx alone regardless of the OS implementation but is unverified. Some Linux doesn’t support bcrypt, so if you want to use nginx basic authentication on your system, just use SHA512 based hashes.

SHA512 is also supported by the new version even in the Apache version of htpasswd, but if it is not supported, it can be generated with the openssl command as shown below, or it can be generated with crypt.3.


  • For OpenSSL
  • For Python

Few words about bcrypt

A prefix that looks like this $2y$12$dNshows us the versions of bcrypt. Subsequent versions bcrypt are due to PHP and OpenBSD implementation bugs, and there is no difference in safety or performance and It can be used as htpasswd.

More information about where 2x prefix are used in BCrypt we can find in link below:

It we think about bcrypt cost, in our case prefix is $2y$12$. This $12$ is called the cost of bcrypt, or rounds, and it affects the strength of bcrypt. If we raise the value of this cost then we have:

  • Increased strength makes it more resistant to offline attacks when htpasswd data is stolen
  • On the other hand, the risk of DoS attacks increases because the consumption of computational resources increases.

Reference about bcrypt cost


This is few tools which we can use

Apache — htpasswd

htpasswd command that comes with Apache server. Apache has a default cost of 5, which is too low, so use -C to specify it explicitly as an option.

root@vagrant:/home/vagrant# htpasswd -nbB -C 12 example 'P@ssw0rd_123'

htpasswd in docker

Apache version of htpasswd is not distributed independently, so if you use it with nginx, it is awkward to handle, so you can also use Docker.

htpasswd in nodejs

Installation and use case:

root@vagrant:/home/vagrant# npm install -g htpasswd
/usr/local/bin/htpasswd -> /usr/local/lib/node_modules/htpasswd/bin/htpasswd
└─┬ htpasswd@2.4.4
├─┬ apache-crypt@1.2.4
│ └── unix-crypt-td-js@1.1.4
├── apache-md5@1.1.5
├── bcryptjs@2.4.3
├── commander@2.20.3
└─┬ prompt@1.1.0
├── colors@1.4.0
├─┬ read@1.0.7
│ └── mute-stream@0.0.8
├── revalidator@0.1.8
├─┬ utile@0.3.0
│ ├── async@0.9.2
│ ├── deep-equal@0.2.2
│ ├── i@0.3.6
│ ├─┬ mkdirp@0.5.5
│ │ └── minimist@1.2.5
│ ├── ncp@1.0.1
│ └─┬ rimraf@2.7.1
│ └─┬ glob@7.1.6
│ ├── fs.realpath@1.0.0
│ ├─┬ inflight@1.0.6
│ │ └── wrappy@1.0.2
│ ├── inherits@2.0.4
│ ├─┬ minimatch@3.0.4
│ │ └─┬ brace-expansion@1.1.11
│ │ ├── balanced-match@1.0.0
│ │ └── concat-map@0.0.1
│ ├── once@1.4.0
│ └── path-is-absolute@1.0.1
└─┬ winston@2.4.5
├── async@1.0.0
├── colors@1.0.3
├── cycle@1.0.3
├── eyes@0.1.8
├── isstream@0.1.2
└── stack-trace@0.0.10
root@vagrant:/home/vagrant# htpasswd -nbBC 12 example 'P@ssw0rd_123'

htpasswd in PHP

To do this we will use password_hash(). More info about this function we can find in link below:


root@vagrant:/home/vagrant# wget
--2021-02-09 17:18:21--
Resolving (
Connecting to (||:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 170 [text/plain]
Saving to: ‘htpasswd.php’
htpasswd.php 100%[===============================================================================>] 170 --.-KB/s in 0s2021-02-09 17:18:22 (7.27 MB/s) - ‘htpasswd.php’ saved [170/170]root@vagrant:/home/vagrant# php htpasswd.php

htpasswd in Python

To do this we will use python bcrypt module.


root@vagrant:/home/vagrant# wget^C
root@vagrant:/home/vagrant# wget
--2021-02-09 17:30:08--
Resolving (
Connecting to (||:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 375 [text/plain]
Saving to: ‘’ 100%[===============================================================================>] 375 --.-KB/s in 0s2021-02-09 17:30:09 (11.8 MB/s) - ‘’ saved [375/375]root@vagrant:/home/vagrant# chmod +x
root@vagrant:/home/vagrant# ./ -C 12 example P@ssw0rd_123



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store

DevOps Consultant. I’m strongly focused on automation, security, and reliability.