暗号化において、ソルト付きチャレンジレスポンス認証メカニズム(SCRAM )は、サーバーに対するユーザーの認証を提供する、最新のパスワードベースのチャレンジレスポンス認証メカニズムのファミリーです。これは、 Simple Authentication and Security Layer (SASL)で規定されているため、 LDAP、HTTP、SMTP、POP3、IMAP、JMAP(電子メール)、XMPP(チャット)、MongoDB、PostgreSQL (データベース)などのサービスへのパスワードベースのログインに使用できます。XMPPでは、SCRAMのサポートは必須です。[ 1 ]
アリスはボブのサーバーにログインしたい。そのためには、自分が名乗っている人物であることを証明する必要がある。この認証問題を解決するため、アリスとボブはパスワードを合意した。アリスはそのパスワードを知っており、ボブもそのパスワードを確認する方法を知っている。
アリスは、パスワードを暗号化されていない接続で平文の形式でボブに送信して検証してもらうこともできますが、そうすると、回線を盗聴しているマロリーにパスワードが知られてしまいます。アリスとボブは、接続を暗号化することでこれを回避しようと試みるかもしれません。しかし、アリスは、暗号化がボブによって設定されたのか、それとも中間者攻撃を行うマロリーによって設定されたのかを知ることができません。そのため、アリスは代わりに、 CRAM-MD5やDIGEST-MD5のようなハッシュ化されたパスワードを送信します。ハッシュなので、マロリーはパスワード自体を入手できません。ハッシュにはチャレンジがソルトされているため、マロリーはそれを1回のログインプロセスにしか使用できません。しかし、アリスはボブに機密情報を伝えたいので、それがマロリーではなくボブであることを確認したいのです。
この問題を解決するため、ボブは認証局(CA)に自身を登録し、認証局が彼の証明書に署名しました。アリスはその署名システムのみに頼ることもできますが、そのシステムに弱点があることを知っています。中間者攻撃がないことをアリスにさらに保証するために、ボブはパスワード(またはそのソルト付きハッシュ)を知っているという証明を作成し、その証明に自身の証明書を含めます。この包含はチャネルバインディングと呼ばれ、下位の暗号化チャネルが上位のアプリケーションチャネルに「バインド」されます。
アリスはボブを認証でき、ボブもアリスを認証できた。これらを合わせると、相互認証が成立する。DIGEST-MD5は既に相互認証を可能にしていたが、しばしば誤って実装されていた。[ 2 ] [ 3 ]
マロリーが中間者攻撃を実行し、認証局の署名を偽造した場合、パスワードのハッシュ値を取得できます。しかし、アリスはハッシュ値にマロリーの暗号鍵を含めていたため、ボブのログインは失敗し、マロリーはアリスになりすますことは一度もできませんでした。完全に透過的な攻撃を行うには、マロリーはアリスが使用するパスワード、またはボブの秘密暗号鍵を知っている必要があります。
ボブはサーバーデータベースのデータ漏洩の話を聞き、ユーザーのパスワードを平文で保存したくないと考えました。彼はCRAM-MD5とDIGEST-MD5ログイン方式について知っていましたが、これらのログイン方式をユーザーに提供するには、ハッシュ化が不十分でソルトのないパスワードを保存しなければならないことを知っていました。彼はその考えが好きではないので、パスワードを平文で要求することにしました。そうすれば、bcrypt、scrypt、PBKDF2などの安全なハッシュ方式でハッシュ化し、好きなようにソルトを付けることができます。しかし、ボブとアリスは依然として上記の問題に直面します。この問題を解決するために、彼らはSCRAMを使用します。SCRAMでは、ボブはPBKDF2を使用してパスワードをソルト付き形式で保存できます。ログイン時に、ボブはアリスにソルトとPBKDF2アルゴリズムの反復回数を送信し、アリスはこれらを使用してボブがデータベースに保存しているハッシュ化されたパスワードを計算します。SCRAMでの以降のすべての計算は、両方の参加者が知っているこの値に基づいています。
すべてのクライアントとサーバーはSHA-1ハッシュアルゴリズムをサポートする必要がありますが、SCRAM はCRAM-MD5やDIGEST-MD5とは異なり、基となるハッシュ関数に依存しません。[ 4 ]代わりに IANA で定義されているハッシュ関数を使用できます。[ 5 ]動機のセクションで述べたように、SCRAM はPBKDF2メカニズムを使用しており、サーバーでデータ漏洩が発生した場合に総当たり攻撃に対する強度を高めます。H選択されたハッシュ関数を、サーバーによって宣伝され、クライアントによって選択されたアルゴリズムの名前で表します。たとえば、「SCRAM-SHA-1」はハッシュ関数として SHA-1 を使用します。
クライアントは、パスワード、ソルト、および以下の計算反復回数から、鍵(ソルト付きパスワード)を生成します。
RFC 5802では、サーバーとクライアント間の4つの連続したメッセージについて以下のように定義しています。
username、およびランダムに生成されたクライアント nonceで構成されますc-nonce。s-nonce、それをサーバーファーストメッセージに追加します。このメッセージには、saltユーザーのパスワード ハッシュのソルト化にサーバーが使用する と反復回数も含まれていますiteration-count。proofverifierメッセージで終了します。Authクライアントとサーバーは、以下の要素からなる同じ変数を持っていることを互いに証明します。
Auth = client-first-without-header + , + server-first + , + client-final-without-proof(カンマで連結)より具体的に言うと、これは次のような形をとります。
= n=username,r=c‑nonce,[extensions,]r=c‑nonce‖s‑nonce,s=salt,i=iteration‑count,[extensions,]c=base64(channel‑flag,[a=authzid],channel‑binding),r=c‑nonce‖s‑nonce[,extensions]証明は以下のように計算されます。
ClientKey = HMAC(SaltedPassword, 'Client Key')ServerKey = HMAC(SaltedPassword, 'Server Key')ClientProof = p = ClientKey XOR HMAC(H(ClientKey), Auth)ServerSignature = v = HMAC(ServerKey, Auth)ここで、XOR演算は同じ長さのバイト列に適用され、は の通常のハッシュです。とはそのままの文字列です。H(ClientKey)ClientKey'Client Key''Server Key'
ClientKeyサーバーは、計算結果から保存されている値とClientProof比較することで、クライアントを認証できます。H(ClientKey)
クライアントは、直接計算および比較を行うことでサーバーを認証できるServerSignature。
サーバーはユーザー名salt、、、、のみを保存します。サーバーは、で暗号化されたクライアント証明から復元されるため、に一時的にアクセスiteration-countできます。H(ClientKey)ServerKeyClientKeyH(ClientKey)
クライアントは、 だけを必要としますpassword。
チャネルバインディングとは、中間者攻撃を防ぐための戦略の一つで、相互認証を提供するアプリケーション層を、下位層(主に暗号化層)に「バインド」し、接続のエンドポイントが両層で同じになるようにするものです。チャネルバインディングには、大きく分けてユニークチャネルバインディングとエンドポイントチャネルバインディングの2種類があります。前者は特定の接続が使用されることを保証し、後者はエンドポイントが同じであることを保証します。
チャネルバインディングにはいくつかの種類があり、それぞれの種類にはチャネルバインディング固有のプレフィックスがあります。[ 6 ]各チャネルバインディングの種類は、チャネルとエンドポイント間で固有の情報を提供するチャネルバインディングデータのコンテンツを指定します。たとえば、tls-server-end-pointチャネルバインディングの場合、それはサーバーの TLS 証明書です。[ 7 ]アプリケーション層として SCRAM を使用したチャネルバインディングのユースケースの例としては、下位層としてTransport Layer Security (TLS) が挙げられます。TLS は通信が暗号化されているため、受動的な盗聴から保護します。ただし、クライアントがサーバーを認証しない場合 (たとえば、サーバーの証明書を検証するなど)、中間者攻撃を防ぐことはできません。このため、エンドポイントは互いに自身の ID を保証する必要があり、これは SCRAM によって提供できます。
gs2 -cbind-flag SCRAM変数は、クライアントがチャネルバインディングをサポートしているかどうか、またはサーバーがチャネルバインディングをサポートしていないと考えているかどうかを指定します。c-bind-inputには、 gs2-cbind-flag、チャネルバインディング固有のプレフィックス、およびチャネルバインディングデータ自体が含まれます。
SCRAMではチャネルバインディングはオプションであり、gs2-cbind-flag変数はダウングレード攻撃を防止します。
サーバーがチャネルバインディングをサポートする場合、通知するSCRAMアルゴリズム名に「-PLUS」という文字シーケンスを追加します。