Basic認証とDigest認証についての基礎知識

Basic認証とDigest認証って言葉は聞いたことあったけども、理解していなかったのでちょっと調べてみました。

Webサイトの閲覧に使うプロトコル「HTTP」が備える、最も基本的なユーザ認証方式。
アクセスの制限されたWebページにアクセスしようとすると、Webブラウザでユーザ名とパスワードの入力を求め、サーバでアクセスを許可しているユーザに一致すると、ページを閲覧することができる。
http://e-words.jp/w/BASICE8AA8DE8A8BC.html

よく特定のページとかにアクセスした時にユーザー名とパスワードの入力を要求されるやつらしい。
これをRails3で使うにはauthenticate_or_request_with_http_basicメソッドを使う。
ブロック引数に、リクエストから抽出したユーザー名とパスワードが渡されるので、一致するかどうかを判定する。

 class BlogController < ApplicationController
   USERNAME = "kazooto"
   PASSWORD = "xxxxxx"

   before_filter :authenticate
   
   def authenticate
     authenticate_or_request_with_http_basic do |name, password|
       name == USERNAME && password == PASSWORD
     end
   end
end
  • Digest認証

Digest認証(ダイジェストにんしょう)とは、HTTPの認証方法の一つ。ユーザ名とパスワードをMD5でハッシュ(ダイジェスト)化して送る。Basic認証では防げなかった盗聴や改竄を防ぐために考案された。

Basic認証のパスワードが暗号化されてるバージョンって考えればいいんだろうか?

Railsでは、authenticate_or_request_with_http_digestメソッドを使う。
引数としてレルム(REALM)を指定する。
ブロック引数としてユーザー名が渡ってくるので、ユーザー名に対応するハッシュ化済みパスワードを返す。

 class BlogController < ApplicationController
   REALM = "myapplication"
   USERS = {"kazooto" => ha1_password("kazooto", "xxxxxx")}
   
   def self.ha1_password(user, password)
     Digest::MD5::hexdigest([user, REALM, password].join(":"))
   end

   before_filter :authenticate
   
   def authenticate
     authenticate_or_request_with_http_digest(REALM) do |name|
       USERS[name]
     end
   end
end
  • まず、あらかじめサーバ側にパスワードの MD5 メッセージダイジェストを保存しておきます (ユーザ登録に相当)。
  • クライアントが Digest 認証を行うページにやってくると、サーバはクライアントにランダムな文字列を渡します。
  • クライアントはパスワードの MD5 メッセージダイジェストを生成します。
  • さらにクライアントは、生成したメッセージダイジェストの末尾に、サーバから受け取ったランダムな文字列をくっつけて、 ひとつの文字列にします。
  • クライアントは、生成した文字列全体の MD5 メッセージダイジェストをサーバに送信します。 なお、このときサーバから送られてきたランダムな文字列もそのまま送り返します。
  • サーバは、あらかじめ用意してあったパスワードの MD5 メッセージダイジェストの末尾に、 クライアントから送られてきたランダムな文字列 (元々はサーバが生成したもの) をくっつけて、 ひとつの文字列にします。
  • サーバは、この文字列全体の MD5 メッセージダイジェストを生成し、 クライアントから送信されてきたメッセージダイジェストと比較します。 もし一致したら認証成功・一致しなかったら失敗です。