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.
Examples:
- For OpenSSL
- For Python
Few words about bcrypt
A prefix that looks like this $2y$12$dN
shows 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
Tools
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'
example:$2y$12$Y7A5LKaEB2uqhQuyDD.2tu0E1mSEUNF3VvoLs4YIc57IdpVaUqcCqroot@vagrant:/home/vagrant#
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
/usr/local/lib
└─┬ 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.10root@vagrant:/home/vagrant# htpasswd -nbBC 12 example 'P@ssw0rd_123'
example:$2a$12$ejx3AV8e38XDA6qjNe2iOO8zcKF66R8lPMu7B8Giu4NTomprpeYWy
htpasswd in PHP
To do this we will use password_hash()
. More info about this function we can find in link below:
Example:
root@vagrant:/home/vagrant# wget https://gist.githubusercontent.com/spy86/cee57edd7095377775e2fa0f7581f9ce/raw/fa8f2ebcd4b3f15f44248adf029909161d4ee995/htpasswd.php
--2021-02-09 17:18:21-- https://gist.githubusercontent.com/spy86/cee57edd7095377775e2fa0f7581f9ce/raw/fa8f2ebcd4b3f15f44248adf029909161d4ee995/htpasswd.php
Resolving gist.githubusercontent.com (gist.githubusercontent.com)... 151.101.112.133
Connecting to gist.githubusercontent.com (gist.githubusercontent.com)|151.101.112.133|: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
example:$2y$12$tVfoAkKgeiOuQ/hqS7ruW.kB693A59bnto9/Ty.3B6bOb9DShipU2
htpasswd in Python
To do this we will use python bcrypt module.
Example:
root@vagrant:/home/vagrant# wgethttps://gist.githubusercontent.com/spy86/f6facd1a1f95d45cf6b892d9fe99b53d/raw/5b262479d9fd552df9ce4fce240ed997798f0331/htpasswd.py^C
root@vagrant:/home/vagrant# wget https://gist.githubusercontent.com/spy86/f6facd1a1f95d45cf6b892d9fe99b53d/raw/5b262479d9fd552df9ce4fce240ed997798f0331/htpasswd.py
--2021-02-09 17:30:08-- https://gist.githubusercontent.com/spy86/f6facd1a1f95d45cf6b892d9fe99b53d/raw/5b262479d9fd552df9ce4fce240ed997798f0331/htpasswd.py
Resolving gist.githubusercontent.com (gist.githubusercontent.com)... 151.101.112.133
Connecting to gist.githubusercontent.com (gist.githubusercontent.com)|151.101.112.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 375 [text/plain]
Saving to: ‘htpasswd.py’htpasswd.py 100%[===============================================================================>] 375 --.-KB/s in 0s2021-02-09 17:30:09 (11.8 MB/s) - ‘htpasswd.py’ saved [375/375]root@vagrant:/home/vagrant# chmod +x htpasswd.py
root@vagrant:/home/vagrant# ./htpasswd.py -C 12 example P@ssw0rd_123
example:$2b$12$zfkL1GKlWYP9lykN6cj/geUlw.SCc45CNwpi.39SWwCfHYbJ3OsTu