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

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 Python

Few words about bcrypt

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

Apache — htpasswd

root@vagrant:/home/vagrant# htpasswd -nbB -C 12 example 'P@ssw0rd_123'
example:$2y$12$Y7A5LKaEB2uqhQuyDD.2tu0E1mSEUNF3VvoLs4YIc57IdpVaUqcCq
root@vagrant:/home/vagrant#

htpasswd in docker

htpasswd in nodejs

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.10
root@vagrant:/home/vagrant# htpasswd -nbBC 12 example 'P@ssw0rd_123'
example:$2a$12$ejx3AV8e38XDA6qjNe2iOO8zcKF66R8lPMu7B8Giu4NTomprpeYWy

htpasswd in PHP

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

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

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

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