Webサイトにアクセスしてもらうときに、ユーザ認証をすることができます。
その方法にはBasic認証とDigest認証の2つがあります。
Basic認証はBASE64というエンコードをしてますが、基本的には平文でIDとPWを送ります。ダイジェスト認証は、暗号化します。

■1.Basic認証について
(1)Basic認証の設定
httpd.comfに設定を書く方法と、.htaccessという設定ファイルに設定を書く方法の2つがあります。
一般の利用者がhttpd.confを直接設定するのは適切ではないため、ユーザや部門などで権限を与えられたフォルダごとに設定をするのであれば、.htaccessをつかいます。

①PWの設定
どちらの方法でも、PWの設定が必要です。
これは、htpasswdを使います。

# htpasswd -c /etc/httpd/conf/.htpasswd user1
-c:新規ファイルを作成
ここで、パスワードを聞かれるので2回入力します。
※-bオプションを付けて、以下のように1行で実行することも可能です。
# htpasswd -c -b /etc/httpd/conf/.htpasswd user1 passwd

ファイルをみてみよう。
[root@localhost conf]# cat .htpasswd
user1:$apr1$e3I6gNRm$411gIIUFlAJNJPmxw0AUr/
user2:$apr1$wZX4VsAi$aAMRN9Gcq64Su0idZ0KPC/

※ここで、htpasswdは特殊な暗号方式であり、md5を使っているとはいえ、単純なものではないようだ。ちなみに、2つ目の$と3つ目の$に挟まれた文字がSaltで、3つ目の$の右側は、Saltとパスワードに対して暗号処理をしている。なので、user1とuser2はどちらも同じパスワード(passwd)なのであるが、ここに記載された値は違っている。また、apr1の1はMD5を意味しているようで、違うハッシュを使う場合は値が変わるようだ。
→htpasswdのアルゴリズムはよくわからない(apache特有らしい)。ただ、SHA1は単純なはずなので、-sでSHA1によるハッシュをしてみた。以下にあるように、パスワードをSHA1でハッシュしてBase64しているという記載があり、実際にやってみたが、計算が合わない。※時間があるときにやりなおしたい。
https://httpd.apache.org/docs/2.4/misc/password_encryptions.html

②フォルダに配置した.htaccessを使う場合
BASIC認証をしたいフォルダに.htaccessファイルを置き、以下を記載します。同時に、先の.htpasswdファイルも配置します。

AuthType Basic
AuthName "Enter yourID and password"
AuthUserFile /etc/httpd/conf/.htpasswd
require valid-user

※最後はユーザを限定しないという意味。特定のユーザに限定する場合は、require user user1 などとユーザ名を記載する。
※本当は、公開サーバの場所に.htpasswdを置いてはいけない。

それと、httpd.conf にも設定を上書きできるように、AllowOverride All を入れた。これを入れないと動かなかったが、他のサイトを見ると、記載していなかったので、ちょっと不思議だ。
vi /etc/httpd/conf/httpd.conf

<Directory "/var/www/html/basic">
    AllowOverride All
</Directory>

パケットキャプチャをしてみると、「user1:passwd」という文字がBASE64エンコードされて、「dXNlcjE6cGFzc3dk」として送信されていることがわかる。

(2)Basic認証のシーケンス
PC→Webサーバに通信をしてスタートです。
①Webサーバにアクセス(この時点で、認証があるとは知らないのでPWは送らない
②Webサーバからのレスポンス 401 Unauthorizedを返す。つまり、認証が必要です!と。また、このときに、WWW-Authenticate:Basec realm=とあり、BASIC認証であることがわかる
③これを受けて、PCのブラウザは認証画面をユーザに提示する。(このあたりはブラウザが自動でやってくれる。ブラウザの機能である)
④ユーザIDとPWをブラウザに入力。「OK」などのボタンを押すと、IDとパスワードをBase64でエンコードしてWebサーバに送る

■2.Digest認証の場合
(1)Digest認証の設定
・.htaccessを使わずに、httpd.confに直接書く。なんどか失敗した。ちょっとした文字のミスでもうまく動いてくれないので面倒だ。うまく動いているのをコピペして、その後、少しずつ直していくのがいいだろう。
・まず、ユーザとPWを作る。先と同様に、-cで新規作成、注意点は、'Digest'というのが領域名(realm)になるが、このあとのhttpd.confのAuthNameと一致させないと認証が成功しない。理由は、認証のハッシュにrealmの値を使っているからである。

htdigest -c /var/www/html/digest/.htdigest 'Digest' user3

では、作成された.htdigestの中身をみてみよう。
# cat ./.htdigest
user3:Digest:12e44928af6c4b9614dab33535b380c7
↑ユーザ名 ↑Realm ↑「ユーザ名:realm:パスワード」をMD5でハッシュ
※A1=ユーザ名:realm:パスワード と記載される場合がある。となると、上記は以下になる。
ユーザ名:Realm:A1のMD5ハッシュ値

ためしに計算してみよう。user3:Digest:passwd
以下などのサイトで user3:Digest:passwd のmd5を計算する。
https://lazesoftware.com/tool/hash/

すると、以下になり、.htdigestファイルに保存された内容と同じである。
12e44928af6c4b9614dab33535b380c7
・viで /etc/httpd/conf/httpd.confを設定。以下を追加

<Directory "/var/www/html/digest">
    AuthType Digest
    AuthName "Digest"
    AuthUserFile "/var/www/html/digest/.htdigest"
    Require valid-user
</Directory>

(2)Digest認証のシーケンス
BASIC認証との比較をしながら
①Webサーバにアクセス(この時点で、認証があるとは知らないのでPWは送らない
http://x.x.dom/abc.html
②Webサーバからのレスポンス401は同じ。このとき、WWW-Authenticate:Digest realmとあり、ダイジェスト認証であることがわかる。加えて、nonce、algorithim(多くはMD5)という情報が送られる。ここで、nonceがサーバから送られるワンタイムパスワードのようなもの。(チャレンジレスポンス認証のチャレンジと思ってもいい)

このときの情報は以下
・realm(リアルム): (例)Digest 
・nonce:サーバが作成するワンタイムパスワード
・algorytm:アルゴリズム (例)md5

③PCはWebサーバに、ユーザ名と、パスワードの代わりにnonceをベースに作成したresponseを返します。
このときに送る情報は以下
・username:ユーザ名 (例)user3
・realm(リアルム): (例)Digest 
・nonce:サーバが作成するワンタイムパスワード
・algorytm:アルゴリズム (例)md5
・url
・qop:auth
・nc:そのnonceを使うのは何回目か
・cnonce:クライアントが作るワンタイムパスワード
・response: ★
※パスワードそのものは送らない

【レスポンスの計算方法】
https://ja.wikipedia.org/wiki/Digest%E8%AA%8D%E8%A8%BC

response = MD5( MD5(ユーザ名 ":" realm ":" パスワード) ":" nonce ":" nc ":" cnonce ":" qop ":" MD5(HTTPのメソッド ":" コンテンツのURI) )
先ほどのA1を使って書き換えると以下になる。
response = MD5( MD5(A1) ":" nonce ":" nc ":" cnonce ":" qop ":" MD5(HTTPのメソッド ":" コンテンツのURI) )
サーバ側では、すでに書いたように、A1=「ユーザ名:realm:パスワード」のハッシュ値を、あらかじめ計算して.htdigestなどにかに格納している。
pythonでresponseを計算すると、以下のようになる。適宜、値を入れてほしい。
------------
import hashlib
username = "user1"
realm = "abc"
password = ""
nonce = "tedakote"
uri = "/content/index.html"
algorithm = "MD5"
qop = "auth"
nc = "00000001"
cnonce="cetadae"
method="GET"
#計算する場合は以下
A1 = username + ":" + realm + ":" + password

#ハッシュ値を求める
md5_A1 =hashlib.md5(A1.encode()).hexdigest()
#または、A1=「ユーザ名:realm:パスワード」のハッシュ値を、あらかじめ計算して.htdigestなどに格納している場合は以下を記載
#md5_A1 = "34f34729155c6c295fb52984e29f899d"
A2 = method + ":" + uri
md5_A2 = hashlib.md5(A2.encode()).hexdigest()
#responseの計算
response = hashlib.md5(":".join([md5_A1,nonce, nc, cnonce, qop, md5_A2]).encode()).hexdigest()
print('A1 =', A1)
print('md5_A1 =', md5_A1)
print('A2 =', A2)
print('md5_A2 =', md5_A2)
print('response =', response)



以下も丁寧に記載がある。
https://laboradian.com/setting-up-digest-auth/