安全なパスワード認証を支えるSRPプロトコル
はじめに
こんにちは、@caru_iniです。今回は、インターネットの安全なパスワード認証を支える SRP プロトコルについて紹介していきます。
SRP (Secure Remote Password) とは
Secure Remote Password (SRP) は、パスワード認証のための認証キー交換プロトコルです。
1997 年にスタンフォード大学で開始されたプロジェクトで、安全、利便性、オープン性、シンプルさを目指して開発されました。
SRP は、パスワードをサーバに送信することがないので、盗聴や中間者攻撃から保護され、安全な認証を提供します。
実際に Amazon Cognito などのサービスで採用されていることもあり、実用性が高いプロトコルです。
主な特徴
SRP は、主に以下の特徴を持っています。
- パスワードをサーバに送信しない
- サーバ側にパスワードのハッシュ値を保存しない
- 秘密鍵はすべて1回限りのランダムな値
おおまかな流れ
はじめから数式を使って説明すると理解が難しいので、まずは簡単な仕組みとおおまかな流れを理解してから、数式を見ていきましょう。
登録時
ユーザーはユーザー名とパスワードを入力すると、クライアント側でランダムなソルトやメールアドレス、パスワードから生成される検証子を生成します。
検証子を用いると、サーバ側でパスワードを保存することなく、パスワードの正当性を検証できます。検証子は不可逆であり、検証子から元のパスワードを復元することはできません。
認証時
最初に、クライアント側でランダムな秘密鍵 a
とそれから生成される効果鍵 A
を生成します。
クライアントはユーザー名とともに公開鍵 A
をサーバに送信します。
サーバ側でも同様にランダムな秘密鍵 b
と検証子v
から生成される公開鍵 B
を生成します。
その後、サーバーは検証子とソルトが保管されているデータベースからソルトを取得し、ソルトと公開鍵B
をクライアントに送信します。
クライアントとサーバーは、それぞれの公開鍵 A
と B
を用いて共有鍵を生成し、それを用いてセッションキーを生成します:
クライアントは、ユーザー名、パスワード、共有鍵、ソルトを用いてセッションキーを生成し、
それをハッシュ化したものをサーバに送信します。
サーバに送信します。
サーバーは、検証子、ソルト、共有鍵を用いてセッションキーを生成します。
最後に、サーバーでセッションキー(正確にはそのハッシュ)が一致するかを確認し、認証結果をクライアントに送信します。
なぜセッションキーが一致するのかは、この後の数学的な説明で詳しく説明します。
数学的な説明
数学的な説明をすると、以下のような数式になります。
記号
-
: ハッシュH() -
: 非常に大きく安全な素数。javascript のN BigInt
に入り切らないほど大きい -
: modulog での生成元N -
: SRP-6a では、k k = H(N, g) -
: ソルトs -
: ユーザー名I -
: パスワード(平文)p -
: ハッシュ化されたソルトとパスワード。x x = H(s, p) -
,a : ランダムな秘密鍵b -
,A :B ,a から生成される公開鍵。後述b -
: ランダムスクランブリングパラメータ。後述u -
,S_c : クライアントとサーバーのセッションキーS_s -
:K をハッシュ化したもの。正しいとき、S K_c = K_s
使用する性質 (補足)
- 指数法則:
(a^b)^c = a^{bc} -
の性質:mod (a + b) \mod N = (a \mod N + b \mod N) \mod N
例えば、a = 2 b = 3 の場合、N = 5 (2 + 3) \mod 5 = (2 \mod 5 + 3 \mod 5) \mod 5 = 0
要件
ユーザーは、
または B == 0 (\mod N) を受信した場合に中止する。 u == 0
ホストは、を検出した場合に中止する。 A == 0 (\mod N)
ユーザーは先にを提示しなければなれない。もしサーバーが K の不一致を検知した場合、サーバーは自分の持つ K を提示せずに中止する。 K
http://srp.stanford.edu/design.html より引用
登録時
- ユーザーは、ユーザー名
とパスワードI を入力し、クライアント側でランダムなソルトP と検証子s を生成します。v
- サーバーに送信・保存されるのは、
I
,s
,v
と任意の他の情報のみです。
認証時
- クライアントは、ランダムな秘密鍵
とそれから生成される公開鍵a を生成します。A
- サーバーも同様に、ランダムな秘密鍵
と検証子から生成される公開鍵b を生成します。B
- クライアントは、ユーザー名
と公開鍵I をサーバーに送信します。A - サーバーは、ユーザー名
からソルトI を取得し、公開鍵s をクライアントに送信します。B - クライアントとサーバーは、それぞれの公開鍵
,A から共有鍵B を生成します。u
- クライアントは、ユーザー名
, パスワードI , 共有鍵P , ソルトu からセッションキーs を生成します。K
- サーバーは、検証子
, ソルトv , 共有鍵s からセッションキーu を生成します。S_s はそれをハッシュ化したものです。K
-
であれば、認証は成功です。K_c = K_s
S_c と S_s が一致するのか
なぜ よって、
同様に、
指数法則より、
よって、
よって、
まとめ
SRP プロトコルの特徴や仕組み、数学的な説明を紹介しました。
最初はとても複雑な処理かと思って身構えていましたが、実際は高校数学の範囲で理解できる内容で、とても興味深いものでした。
認証の仕組みに興味を持つとてもいい機会になりました。
このような技術が世の中を支えていることを知ると、非常に感慨深いですね。
間違いやご指摘があれば、下記のコメント欄 or X までお知らせいただけると幸いです。
参考文献
Discussion