Basic認証について考えてみる(2008年6月6日)
盗聴による危険があるとはいえ、何より実装が簡単なBasic認証。
裏側で何が起こっているのか正確に把握したい。
仕組みとしては単純
(1) HTTPクライアントであるWebブラウザがリクエストの度に毎回 『ユーザー名/パスワード』 のセットをWebサーバーに送信。
(2) Webサーバーは上記が正しければページを返す。『ユーザー名/パスワード』 のセットが間違っているもしくは送信しなかった場合は、レスポンス 『401 Authorization Required』 を返す。
HTTPプロトコル仕様上、クライアント側から見て毎回
『接続 → ファイル要求 → ファイル受信 → 切断』
を繰り返している為、サーバー側では毎回要求に対しての認証処理を行う必要がある。
Basic認証では、毎回クライアントから『ユーザー名/パスワード』の情報を送信することで認証するという単純な考え方で実現されている。
(1) の『ユーザ名/パスワード』の送信はクライアントから送信するHTTPヘッダーに下記の文字列を加えることで実現する。
-----------------------------------------------------------
Authorization: Basic aG9nZTptb2dl
-----------------------------------------------------------
『aG9nZTptb2dl』は、ユーザ名:パスワードを Base64 エンコードした文字列で可逆変換。下記のようにエンコード/デコード できる。(ユーザー:hoge パスワード:moge の場合)
[hyaku@hyakutem hyaku]$ echo -n 'hoge:moge' |nkf -MB
aG9nZTptb2dl[hyaku@hyakutem hyaku]$
[hyaku@hyakutem hyaku]$ echo -n 'aG9nZTptb2dl' |nkf -mB
hoge:moge[hyaku@hyakutem hyaku]$
(2) のサーバー側では、.htpasswd などに記載された『ユーザー/パスワード』の情報と受信した『ユーザー/パスワード』が一致するかチェックする。
---<.htpasswdの生成例と中身>----------------------------
[hyaku@hyakutem hyaku]$ htpasswd -bc .htpasswd hoge moge
Adding password for user hoge
[hyaku@hyakutem hyaku]$ cat .htpasswd
hoge:QCFLlFCom8GDU
[hyaku@hyakutem hyaku]$
-----------------------------------------------------------------------
上記のパスワード部分は、通常 crypt により暗号化されており、不可逆変換。(総当たりのパスワードクラックにより解読可能だが、時間はかかるという状態。)
Webサーバーは、クライアントから受信したパスワードと、上記.htpasswdファイルのパスワードの最初の2文字(salt)を使用してパスワードの一致をチェックする。(受信したパスワードを暗号化して、暗号化したパスワードの一致をチェックする)
[hyaku@hyakutem hyaku]$ perl -e 'print crypt("moge","QC")'
QCFLlFCom8GDU[hyaku@hyakutem hyaku]$
ポイントは、『毎回クライアントからパスワードを送信していて、かつ、Base64 エンコードしているだけなので簡単に元に戻せる。』というところか。そう考えると、通信自体がすべてSSL等で暗号化されていれば基本的には問題ない。しかし、ブラウザが間違えて違うサイト(SSL暗号化なし)にパスワードを送ってしまったらどうなるの? 等、『そんなことはブラウザつくった人に聞いてくれ!』ということも考えなくてはならなくなるのか。難しいところだ。