1. Introduction (はじめに)
1. Introduction (はじめに)
TLS [RFC5246] では、すべてのセッションに次のように計算される master_secret があります。
master_secret = PRF(pre_master_secret, "master secret",
ClientHello.random + ServerHello.random)
[0..47];
ここで、pre_master_secret は何らかの鍵交換プロトコルの結果です。たとえば、ハンドシェイクが RSA 暗号スイートを使用する場合、この値はクライアントによって一様にランダムに生成されますが、Ephemeral Diffie-Hellman (DHE) 暗号スイートの場合、Diffie-Hellman 鍵合意の結果です。
[TRIPLE-HS] で説明されているように、RSA 鍵交換と DHE 鍵交換の両方で、アクティブな攻撃者は2つの TLS セッションを同期させて、同じ master_secret を共有させることができます。クライアントが認証されていない RSA 鍵交換の場合、これは次のように実現されます。クライアント C がサーバー A に接続するとします。C は、A が悪意のあるサーバーであり、A がバックグラウンドで正直なサーバー S に接続して両方のハンドシェイクを完了していることに気付いていません。簡単にするために、C と S は RSA 暗号スイートのみを使用すると仮定します。
-
C は A に
ClientHelloを送信し、A はそれを S に転送します。 -
S は
ServerHelloを A に送信し、A はそれを C に転送します。 -
S は、その証明書チェーンを含む
Certificateを A に送信します。A はそれを自分の証明書チェーンに置き換えて C に送信します。 -
S は
ServerHelloDoneを A に送信し、A はそれを C に転送します。 -
C は、A の公開鍵で暗号化された
pre_master_secretを含むClientKeyExchangeを A に送信します。A はpre_master_secretを復号化し、S の公開鍵で再暗号化して S に送信します。 -
C は
Finishedを A に送信します。A は S との接続のためのFinishedを計算し、それを S に送信します。 -
S は
Finishedを A に送信します。A は C との接続のためのFinishedを計算し、それを C に送信します。
この時点で、両方の接続(C と A の間、および A と S の間)には、同じ pre_master_secret、ClientHello.random、ServerHello.random、およびセッション識別子や(オプションで)セッションチケットを含むその他のセッションパラメータを共有する新しいセッションがあります。したがって、master_secret 値は2つのセッションで等しくなり、2つの接続上のサーバー ID が異なっていても、C と S の両方で同じセッション ID に関連付けられます。C は A の証明書しか見ておらず、A と S の接続については認識していないことを思い出してください。さらに、2つの接続上のレコードキーも同じになります。
上記のシナリオは、TLS が異なる接続で使用されるマスターシークレットとキーが異なることを保証しないことを示しています。クライアント認証が使用されている場合でも、2つのセッションがクライアント ID とサーバー ID の両方で異なることを除いて、シナリオは機能します。
ハンドシェイクが DHE 暗号スイートを使用する場合、同様のシナリオを実現できます。クライアントまたはサーバーが RSA または DHE の使用を好まない場合でも、攻撃者は hello メッセージで RSA または DHE のみを提供することで、それらの使用を強制できることに注意してください。Ephemeral Elliptic Curve Diffie-Hellman (ECDHE) 暗号スイートを使用するハンドシェイクも、任意の明示的な曲線が許可されている場合、または小さなサブグループを持つ曲線が使用されている場合は脆弱です。より強力な敵対者に対しては、Secure Remote Password (SRP) や Pre-Shared Key (PSK) などの他の鍵交換も脆弱であることが示されています [VERIFIED-BINDINGS]。
A が2つの接続を同期させると、キーは両側で同じになるため、A は離れて C と S の間でメッセージを透過的に転送し、必要に応じて読み取りと変更を行うことができます。鍵交換の文献では、C と S は秘密を共有していますが、両方ともその秘密が A とのみ共有されていると考えているため、このような発生は未知の鍵共有(unknown key-share)攻撃と呼ばれます。それ自体では、これらの攻撃は正直な当事者間の完全性や機密性を損なうことはありませんが、C と S に対するなりすまし攻撃を開始するための有用な出発点を提供します。
C が A との新しい接続でセッションを再開しようとしているとします。A はその後、新しい接続で S とのセッションを再開し、C と S の間で簡略化されたハンドシェイクメッセージを変更せずに転送できます。簡略化されたハンドシェイクは認証のためにマスターシークレットのみに依存し、クライアントまたはサーバーの ID に言及しないため、両方のハンドシェイクは正常に完了し、同じセッションキーと同じハンドシェイクログになります。A はまだ接続キーを知っており、C と S の両方にメッセージを送信できます。
重要なことに、新しい接続では、ハンドシェイクログでさえ C と S で同じであり、安全な再ネゴシエーション指示拡張 [RFC5746] や TLS チャネルバインディング [RFC5929] など、finished メッセージの一意性に依存する中間者保護スキームを無効にします。[TRIPLE-HS] は、このようなセッション同期攻撃に基づくいくつかのエクスプロイトについて説明しています。特に、セッション再開後にクライアント認証された TLS 再ネゴシエーションを破るために [RFC5746] の保護を回避する「トリプルハンドシェイク」と呼ばれる中間者攻撃について説明しています。同様の攻撃は、チャネルバインディング [RFC5929] または TLS からエクスポートされた鍵素材 [RFC5705] に依存するアプリケーションレベルの認証メカニズムに適用されます。
これらの攻撃につながる根本的なプロトコルの問題は、TLS マスターシークレットがそれを生成した完全なハンドシェイクにコンテキストバインドされていないため、セッション間で一意であることが保証されないことです。最初のマスターシークレット計算でこの問題を修正すれば、これらすべての攻撃を防ぐことができます。この仕様では、ハンドシェイクメッセージのログを含めることにより、完全なハンドシェイクで master_secret 値が計算される方法を変更する TLS 拡張を導入します。これにより、異なるセッションは構築によって異なるマスターシークレットを持つようになります。これにより、[TRIPLE-HS] で説明され、[RFC7457] のセクション 2.11 で文書化されている攻撃が防止されます。