web-dev-qa-db-ja.com

安全なチャネルを前提として、ユーザー名とパスワードよりもSCRAMを使用するメリットはありますか?

HTTP経由の通信を考えると

  • sSL暗号化を使用
  • 公開鍵ピン留めを使用してMiTM攻撃を防止する

基本的なアクセス認証に続いて Saltedチャレンジレスポンス認証メカニズム (SCRAM)を使用し、その後すべてのリクエストにトークンを使用することで、セキュリティはどのように向上しますか?

4
qnoid

tl; dr:一般的にはお勧めしませんが、特定の状況では役立つ場合があります

SCRAMの利点

  • パスワードがサーバーに送信されることはありません。送信されるものは次のとおりです。
    • ナンス
    • 反復回数
    • HMAC(PBKDF2(password), "Client Key") XOR HMAC(H(HMAC(PBKDF2(password), "Client Key")), AuthMessage)(真剣に、私はこれを作りません!)
    • HMAC(HMAC(PBKDF2(password), "Server Key"), AuthMessage)
  • サーバーはパスワードを決して知らないため、他のサーバーのユーザーを偽装することはできません(これらのサーバーのソルトがこのサーバーのソルトと異なる限り)

SCRAMの欠点

  • PBKDF2の使用が必要です。 PBKDF2は高速ハッシュよりもはるかに優れていますが、bcryptの方が優れています(現在、Argon2も検討する必要があります)。
  • 計算の複雑さはすべてクライアントが処理する必要があります

最初のポイントは残念ですが、2番目のポイントは本当のキラーです。今やスマートフォンやタブレットはどこにでもあるので、クライアントが安全になるのに十分な反復でPBKDF2をすばやく計算できると思い込むことはできません。

SCRAMが役立つのはいつですか?

SCRAMの用途としては、クライアントは信頼されていますが、サーバーは信頼されていません。これはWebアプリケーションには当てはまりません(「クライアント」はサーバーから送信されたJavaScriptであるため)。ローカルアプリケーションに当てはまる場合もあります。私が考えることができる最良の例は Wikipediaが提供するもの :SMTP、IMAP、およびXMPPです。ここでは、メールまたはチャットクライアントを信頼しているが、潜在的に悪意のあるサードパーティのサーバーに対して認証を行っています。

クライアントが高い反復回数と一意のソルトを強制する場合、不正なCAと組み合わされたDNSハイジャックのリスクを軽減する可能性がありますが、すでに証明書のピン留めでそれを行っています。防御するために残された唯一のものは、悪意のあるyourサーバーです。これは、場合によっては役立ちますが、SCRAMの欠点を上回る場合にのみ役立ちます。

SCRAM could強力なパスワードが使用されることがわかっている場合にサーバーがパスワードを取得しないようにするのに役立ちますが、パスワードは他の場所でも再使用されます(再利用されない場合、なぜあなたはサーバーはそれを知っているかもしれませんか?)残念ながら、これは実際に強制することはできず、idealはとにかく一意のパスワードを使用することになります。


SCRAMはどのように機能しますか?

SCRAMでは、サーバーは以下を保管します。

  • 反復回数
  • ServerKey = HMAC(PBKDF2(password), "Server Key")(_"Server Key"_は既知の定数HMACキーです)*
  • StoredKey = H(HMAC(PBKDF2(password), "Client Key"))(_"Client Key"_の同上)

認証するには:

  1. クライアントはユーザー名とランダムなナンスを送信します
  2. サーバーは独自のランダムなナンスをクライアントのナンスに追加し、ユーザーのナンス、ソルト、およびイテレーションカウントで応答します
  3. クライアントは以下を計算します。
    1. ClientKey = HMAC(PBKDF2(password), "Client Key")
    2. StoredKey = H(ClientKey)
    3. ClientSignature = HMAC(StoredKey, AuthMessage)(ここでAuthMessageは、以前に交換されたすべてのメッセージとナンスの連結で、コンマで区切られています)
    4. _ClientProof = ClientKey XOR ClientSignature_
  4. クライアントはnonceとClientProofをサーバーに送信します
  5. サーバーは以下を計算します:
    1. ClientSignature = HMAC(StoredKey, AuthMessage)
    2. _ClientKey = ClientProof XOR ClientSignature_
    3. ServerSignature = HMAC(ServerKey, AuthMessage)
  6. サーバーはH(ClientKey) == StoredKeyを検証し、クライアントがパスワード(または少なくともClientKey)を知っていることを証明します
  7. サーバーはServerSignatureで応答します
  8. クライアントはServerSignatureを計算し、それをサーバーから返された値と比較して、サーバーがServerKeyを知っていることを確認します

ハッシュの選択、エンコーディング、メッセージフォーマット、チャネルバインディングなどが除外されているため、これはかなり単純化されていますが、それがどのように機能するかについては良い考えが得られるはずです。

* PBKDF2のすべての使用には明らかにソルトと反復カウントも含まれ、SCRAMはdkLenを選択したハッシュの出力長に設定します

3
AndrolGenhald

[〜#〜] rfc [〜#〜] は、次の利点を示しています。

o認証データベースに格納されている認証情報だけでは、クライアントを偽装するには不十分です。データベースが盗まれた場合に、事前に格納された辞書攻撃を防ぐために、情報はソルト化されます。

oサーバーは、クライアントを他のサーバーに偽装する機能を取得しません(サーバー承認プロキシを除く)。

oこのメカニズムでは、バックエンドサーバーとのスーパーユーザー権限を持つプロキシーを必要とせずに、サーバー承認プロキシーを使用できます。

o相互認証はサポートされていますが、名前が付けられるのはクライアントのみです(つまり、サーバーには名前がありません)。

質問では接続のセキュリティのみが考慮されますが、SCRAMではクライアントの資格情報のセキュリティも考慮されます。その最も明確な利点は、ソルトおよびハッシュ形式で送信されるため、サーバーオペレーターがユーザーの資格情報を取得できない一方で、単純なTLS接続ではクリアテキストで移動することです。

1
ThoriumBR

一般的なセキュリティ上の欠陥は、誤ってプレーンテキストのパスワードを記録することです:

トランスポートセキュリティがある場合でも、サーバーにプレーンテキストのパスワードを設定しない方が有利です。トランスポートセキュリティは、攻撃者から保護します。自分の過ちから身を守るには、クライアント側のハッシュが必要です。

0
Sjoerd