Web

Digest認証の設定手順

投稿日:2020年3月23日 更新日:

1. Digest認証とは?

本記事では、HTTP認証(HTTP というプロトコルを利用した認証)の1つである Digest認証の設定手順について説明します。

HTTP認証の中で一番有名(?)な Basic認証 と同じくらい手軽に設定でき、且つセキュリティ的により安全なのが Digest認証です。

Basic認証では入力したパスワードが平文でサーバーに送信される(そのため HTTPSで利用することが必須)のに対して、Digest認証では「ランダムな文字列(チャレンジ) + パスワード」がハッシュ化(分かりにくい文字列に変換される)されて送信されます(*1)。これは、チャレンジ・レスポンス方式と呼ばれます。

(*1) 実際はもう少し複雑です。詳細は RFC 2617 を参照してください。

2. Webサーバーの対応

Apache では Digest認証が使えますが、nginx だと標準では対応していないようです。

Webで簡単に認証を掛けたい場合は、Basic認証 + HTTPS で良いという考えなのかもしれません。

3. Digest認証の設定手順

ここでは Apache 2.4 (on CentOS 7) での手順について説明します。

(1) Digest認証が使えるか確認する

Digest認証を行うには、Apache にDigest認証のモジュールが読み込まれている必要があります。以下のコマンドで確認します(環境によっては、管理者権限が必要かもしれません)。

$ sudo httpd -M | grep digest

実際に実行した例が以下です。

$ sudo httpd -M | grep digest
auth_digest_module (shared)

auth_digest_module というモジュールが読み込まれていることが分かります。

もし何も表示されない場合は、Apache の設定ファイルに、Digest認証モジュールを読み込むための設定を追記する必要があります。その後、Apache を再起動してください。

LoadModule auth_digest_module modules/mod_auth_digest.so

参考

(2) Digest認証のファイルを作成する

Digest認証で使用するユーザー名・パスワード・realm(領域) を記録しておくファイルを作成します。

以下のコマンドで作成します。

$ sudo htdigest -c {ファイルパス} '{領域名}' {ユーザー名}

実行例が以下です。

$ sudo htdigest -c .digestpass 'Digest Auth' foo

実行すると、パスワードを聞いてきますので入力します。

このとき、生成された .digestpass ファイルの内容は例えば以下のようになっています。

$ cat .digestpass
foo:Digest Auth:cce31c0fdaf4d98cdda656f24b7baf4c

(3) Apache の設定ファイルに認証するための記述を行う

ここでは、特定のディレクトリに対して Digest認証を掛ける場合を想定し、そのディレクトリ直下の .htaccess ファイルに設定を記述します。

記述する内容は以下です。

AuthType Digest
AuthName "{認証名}"
AuthUserFile "{認証情報のファイルパス}"
Require valid-user
  • AuthTypeRequire は上記のまま記述します。
  • AuthNameAuthUserFile は、自分が決めた内容を記述します。

一例を示します。

AuthType Digest
AuthName "Digest Auth"
AuthUserFile "/path/to/.digestpass"
Require valid-user

.htaccess への記述のため、Apache を再起動する必要はありません。

以上の設定を行うと、Digest認証が有効になります。

Digest認証のログイン画面 (Chrome)

4. Digest認証でのやり取り

Digest認証でのウェブブラウザとウェブサーバーとのやり取りを抜粋して記載します。

(1) Digest認証が設定されたURLにウェブブラウザでアクセスすると、HTTPステータスコード 401 (Unauthorized) が返され、ウェブブラウザはユーザー名とパスワードの入力を促します。

このとき、ウェブサーバーからウェブブラウザに返されるされる HTTPヘッダには、www-authenticate というフィールドが含まれます。そのフィールドの例を以下に示します(読みやすくするため改行しています)。

www-authenticate: 
    Digest 
    realm="Digest Auth", 
    nonce="lamPKUShBQA=98cbd2bcb9d1099195eb65fb1c514fe2b55bc5a3", 
    algorithm=MD5, 
    qop="auth"

(2) ユーザー名とパスワードを入力してログインボタンを押します。

このとき、ウェブブラウザからウェブサーバーに送信される HTTPヘッダには authorization というフィールドが含まれます。そのフィールドの例を以下に示します(読みやすくするため改行しています)。

authorization:
    Digest 
    username="foo", 
    realm="Digest Auth", 
    nonce="lamPKUShBQA=98cbd2bcb9d1099195eb65fb1c514fe2b55bc5a3", 
    uri="/web-test/003/", 
    algorithm=MD5, 
    response="6ff30b800cf53ba5ba31651ed5da71d5", 
    qop=auth, 
    nc=00000002, 
    cnonce="47fc00956aae926c"

この中の response は、パスワード文字列やその他の情報をハッシュ化した文字列がセットされています。

この情報を受け取ったウェブサーバーは、同じやり方で文字列を生成し、response と一致するかを検証します。一致すればログイン成功です。

5. Digest認証の response を計算してみる

以下の authorization フィールドに記載された response 以外の値を元にして、 response に記述されている文字列を自分で生成してみましょう。

※ HTTPメソッドは GET であり、パスワードは password であることは分かっているとします。

authorization:
    Digest
    username="foo",
    realm="Digest Auth",
    nonce="lamPKUShBQA=98cbd2bcb9d1099195eb65fb1c514fe2b55bc5a3",
    uri="/web-test/003/",
    algorithm=MD5,
    response="6ff30b800cf53ba5ba31651ed5da71d5",
    qop=auth,
    nc=00000002,
    cnonce="47fc00956aae926c"

RFC 2617 に文字列の算出手順が書いてあるのですが、今回使う部分のみを以下に抜粋します。上記のフィールドに出ている項目名がそのまま使われているので、どこにどの値を入れればよいのかはおおよそ検討が付くと思います。詳細はリンク先を参照してください。

A1 = unq(username-value) ":" unq(realm-value) ":" passwd
A2 = Method ":" digest-uri-value
H(data) = MD5(data)
KD(secret, data) = H(concat(secret, ":", data))
request-digest  = <"> < KD ( H(A1), unq(nonce-value)
                                    ":" nc-value
                                    ":" unq(cnonce-value)
                                    ":" unq(qop-value)
                                    ":" H(A2)
                           ) <">

ここに出てくる A1, A2 を元に H(A1), H(A2) を算出し、最後に request-digest を算出します。この request-digestresponse に一致するはずです。

実際やってみると、A1, A2, H(A1), H(A2) は以下となります。

A1    = foo:Digest Auth:password
A2    = GET:/web-test/003/
H(A1) = cce31c0fdaf4d98cdda656f24b7baf4c
H(A2) = 157fb7b768228837518320d7e8abac99

詳細は省きますが、request-digestcce31c0fdaf4d98cdda656f24b7baf4c:lamPKUShBQA=98cbd2bcb9d1099195eb65fb1c514fe2b55bc5a3:00000002:47fc00956aae926c:auth:157fb7b768228837518320d7e8abac99 の MD5 ハッシュ値となり、実際にやってみると 6ff30b800cf53ba5ba31651ed5da71d5 を得ることができました。

※ MD5 のハッシュ値を得るのに、エンコード/デコード/ハッシュ – Tools on Web を使いました。

6. その他のメモ

  • 一度 Digest認証で認証を通ってしまうと、ブラウザを閉じるまでその情報を覚えています。何度も認証を試したい場合は、シークレットウィンドウ (Chrome) の利用をお勧めします。

7. おわりに

正直 Digest認証はあまり使われていない印象です。レンタルサーバーなどでもアクセス制限機能と称して Basic認証が使われていたりします。最初の方でも書きましたが、HTTPS さえ使っていれば Basic認証で問題ないのかもしれません。なんだが残念です。

Web

Basic認証の設定手順

2020.03.24

8. 参考

📂-Web

執筆者:labo


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

Glitch

ブラウザだけで完結するウェブアプリ作成環境 Glitch

ブラウザだけで完結するウェブアプリ作成環境 Glitch を紹介します。

Web

Intersection Observer API を使った画像の遅延読み込み

目次1. 画像の遅延読み込み(遅延ローディング)2. Intersection Observer API3. Intersection Observer API を使って画像を遅延読み込みする例1. …

Web

インストールが可能になるための最低限のウェブサイト(PWA)を作る

インストールが可能になるための最低限のウェブサイト(PWA)を作る方法について説明します。

Web

cron-job.org を利用して特定のURLに定期的にアクセスさせる

cron-job.org というサービスの利用手順について説明します。

web development

Webページが読み込む CSS, JS コードから、実際に使われている部分のみを抽出する

Webページが読み込む CSS, JS コードから、実際に使われている部分のみを抽出する方法を紹介します。