あどけない話

Internet technologies

OpenID

OpenID を勉強しようと、OpenID.ne.jpの説明を読んでみました。素人にはこういう説明でいいんでしょうが、セキュリティの専門家として読むと、これで何が認証されるのか、ブラウザの挙動はどうなるのか、さっぱり分りませんでした。

しょうがないので、バージョン 1.1 の仕様書を読んでみました。これでは RFC にさえなれないぐらい、ひどい質の文章でした。説明が下手だし、言葉が足りないので、まるで分りません。

さらに、バージョン 2.0 の仕様書を読んでみて、ようやく理解できました。はじめから、これを読めばよかったです。(もうちょっと工夫すれば、もっと分りやすくなるとは思いますが。)

認証の手続

結局、Overview の部分が核心をついていました。

登場人物は以下の3人:

  • ブラウザとユーザ
  • OpenID に対応したサービス
  • OpenID サーバ

認証の手続は、以下の通り。

  1. ユーザがブラウザを使って、あるサービスにアクセスする。サービスが認証を要求するので、ユーザは URL を打ち込む。これで認証の手続が始まる。
  2. サービスは、ユーザが打ち込んだ URL を基に、最終的な URL と OpenID サーバを得る。
  3. (省略可)サービスは、OpenID サーバと Diffie-Hellman を使って秘密の値を共有する。
  4. サービスは、認証情報と共にブラウザを OpenID サーバへリダイレクトする。
  5. OpenID サーバは、ユーザにパスワードを要求し、ユーザがパスワードを打ち込む。
  6. OpenID サーバは、認証結果と共にブラウザを元のサービスへリダイレクトする。
  7. サービスは、認証結果を検証する。
    1. 秘密の値を共有しているなら、OpenID サーバが署名(HMAC-SHA1)しているはずなので、それを検証する。
    2. そうでないなら、OpenID サーバに認証結果を問い合わせる。OpenID サーバが署名を検証し、結果を返す。

利用方法

RFC などもそうなのですが、仕様書にはどういうストーリで使うか書かれていないことが多く、理解の妨げになります。補助的な説明が別にあればいいんでしょうが、それも見当たらないので、結局知人と議論して考えてみました。

たとえば、悪意を持ったユーザが自分で OpenID を上げるとします。すると、認証結果は必ず OK になるでしょう。こんな認証機構が信用できるのでしょうか? 結局、なんからの格付けが必要になるはずです。

とうわけで、以下のように利用されるのでしょう。

あらかじめ登録された ID だけにサービスを公開する
ユーザを信頼し、ユーザが信頼する OpenID サーバを信頼することになります。
OpenID サーバのホワイト/ブラックリストを持つ
特定の OpenID サーバを信頼し、そこが認証するユーザを信頼する。

もちろん、これら両方を実装してもいいでしょう。

セキュリティ・ホール

まぁ、これだけだといろいろセキュリティ・ホールがあるので、SSL が必須となっています。

僕が疑問に思うのは、nonce と呼ばれる乱数です。OpenID サーバは、6) で発行する認証結果に、この乱数を付けて返します。サービスは乱数を管理し、乱数が1回しか使えないようにして、再送攻撃(replay attack)を防ぎます。

でもこれだと、サービスは永遠に乱数を捨てれませんね。僕なら、4)においてサービスが乱数を生成し、それを戻してもらうように設計します。それなら、一回使われたら捨てればいいし、使われない場合も賞味期限が切れれば捨てることができます。

さて、どうなんでしょう?