2005-08 / 2005-08-09

前のエントリ: Apache(1.x), mod_ssl で https [Apache]
次のエントリ: HDD増設 [debian]

Digest認証の実装
2005-08-09-2 / カテゴリ: [HTTP] / [permlink]

[2005-07-18-2]の続き。情報元は同じくHTTP 認証: 基本アクセス認証及びダイジェストアクセス認証(RFC2617 日本語訳)
サーバ側の digest 認証の設定は[2005-07-08-3], [2005-05-29-2]

パケットキャプチャすると、サーバ側(Apache 1.3.33/debian)のレスポンスは
HTTP/1.1 401 Authorization Required
Date: Tue, 09 Aug 2005 06:20:01 GMT
Server: Apache/1.3.33 (Debian GNU/Linux) PHP/4.3.10-15 mod_jk/1.2.5 mod_fastcgi/2.4.2 mod_ssl/2.8.22 OpenSSL/0.9.7d
WWW-Authenticate: Digest realm="relm", nonce="98ca43d0f7a1e2641ea305f44db89cca1123568401"
Keep-Alive: timeout=15, max=99
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=iso-8859-1
こんな感じ。
RFC2617に載っている、'algorithm' や 'qop' といった指示子がないな。ま、使用す[べきである]だから、いいのか(qop-options)。必要なのは realm と nonce かな。
algorithm がない場合は、"MD5" 扱いとのこと。

 challenge = "Digest" digest-challenge

 digest-challenge = 1#( realm | [ domain ] | nonce |
                     [ opaque ] |[ stale ] | [ algorithm ] |
                     [ qop-options ] | [auth-param] )

んで、クライアント(mozilla 1.7.6)のリクエスト
GET /~zaki/auth/digest/ HTTP/1.1
Host: www.example.org
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ja-JP; rv:1.7.6) Gecko/20050319
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Authorization: Digest username="zaki", realm="relm", nonce="98ca43d0f7a1e2641ea305f44db89cca1123568401", uri="/~zaki/auth/digest/", response="52b08746ab144ba29cf2fd6fe31174ca"
認証のための HTTP リクエストは Authorization ヘッダ。
 credentials = "Digest" digest-response
 digest-response = 1#( username | realm | nonce | digest-uri
                 | response | [ algorithm ] | [cnonce] |
                 [opaque] | [message-qop] |
                     [nonce-count] | [auth-param] )

んで、
username 使用するユーザ名 (username="zaki")
realm 使用するrealm(レスポンスヘッダにある) (realm="relm" <- スペルミスった)
nonce レスポンスにある nonce そのまま (nonce="98..."
digest-uri リクエストするファイル (uri="/~zaki/auth/digest/")
response ダイジェスト (response="52...")

でもって、response は、
"qop" が "auth" か "auth-int" である場合:
 request-digest = <"> < KD ( H(A1), unq(nonce-value)
                                     ":" nc-value
                                     ":" unq(cnonce-value)
                                     ":" unq(qop-value)
                                     ":" H(A2)
                             ) <">

"qop" 指示子が与えられない場合 (RFC 2069 との互換性のための構文)
    request-digest =
               <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <">

A1 と A2 についての定義は以下を見よ。
とゆーことなので、 "KD(H(A1), unq(nonce-value) ":" H(A2)" ということ。

KD(xx, xx) は
 H(data) = MD5(data)
また
 KD(secret, data) = H(concat(secret, ":", data))
なので、"xx:xx" の md5sum 値

H(xxx) は、"xxx" の md5sum 値

A1 は
 A1 = unq(username-value) ":" unq(realm-value) ":" passwd
で、ユーザ名:zaki, パス:zaki、realm:relm であれば、
$ printf 'zaki:relm:zaki' | md5sum
f85142f6a9b00f64cd3afb151ba80505
こうなる。

A2 は
"qop" 指示子の値が "auth" か指定されない場合、A2 は:
A2 = Method ":" digest-uri-value

"qop" の値が "auth-int" ならば、A2 は:
A2 = Method ":" digest-uri-value ":" H(entity-body)
で、/~zaki/auth/digest/ への GET リクエストであれば、
$ printf 'GET:/~zaki/auth/digest/' | md5sum
b513229595a7eff3223d5412614d2ba4
となる。

で、元の "KD(H(A1), unq(nonce-value) ":" H(A2)" に戻ると、サーバのレスポンスの nonce が "98ca43d0f7a1e2641ea305f44db89cca1123568401" なので
$ printf 'f85142f6a9b00f64cd3afb151ba80505:98ca43d0f7a1e2641ea305f44db89cca1123568401:b513229595a7eff3223d5412614d2ba4' | md5sum
52b08746ab144ba29cf2fd6fe31174ca
になる。



んーと、Digest認証は、パスワードが平文でネットワークを流れないから安全・サーバ上にパスワードを平文で保存しないので安全って聞くけど、前者は良いとして、後者は、パスワードファイル(例えば .htpasswd)の中身が
zaki:relm:f85142f6a9b00f64cd3afb151ba80505
こーなってんだよね…。'zaki'って生パスワードではないけど、強調するほど安全じゃないよな。このファイル(のハッシュ値)と nonce 値さえ取られてしまえば、あとは md5sum 計算するだけだし。

多分
前のエントリ: Apache(1.x), mod_ssl で https [Apache]
次のエントリ: HDD増設 [debian]

2013 : 01 02 03 04 05 06 07 08 09 10 11 12
2012 : 01 02 03 04 05 06 07 08 09 10 11 12
2011 : 01 02 03 04 05 06 07 08 09 10 11 12
2010 : 01 02 03 04 05 06 07 08 09 10 11 12
2009 : 01 02 03 04 05 06 07 08 09 10 11 12
2008 : 01 02 03 04 05 06 07 08 09 10 11 12
2007 : 01 02 03 04 05 06 07 08 09 10 11 12
2006 : 01 02 03 04 05 06 07 08 09 10 11 12
2005 : 01 02 03 04 05 06 07 08 09 10 11 12
2004 : 01 02 03 04 05 06 07 08 09 10 11 12

最終更新時間: 2013-05-02 16:12