ChannelManager クラスのコード分析 (CNG の例)

CNG (Cryptography Next Generation) のセキュリティで保護された通信の例では、ChannelManager クラスでこの例に用いるプロセス間通信 (IPC) インフラストラクチャを提供します。

このクラスは次の目的に使用します。

  • 名前付きパイプの作成、オープン、クローズ、および破棄

  • アプリケーション制御フラグ、チャネル名、デジタル署名、暗号化キー、およびメッセージの送受信

ここで説明している例の概要およびバージョンの説明については、「CNG (Cryptography Next Generation) のセキュリティで保護された通信の例」を参照してください。

ChannelManager.cs ファイルの内容

ChannelManager.cs ファイルには、次のクラスおよびメソッドが含まれています。

  • ChannelManager クラス:

    • コンストラクター : 名前付きパイプを作成し、そのパイプの一方の終端で接続を待機します。名前付きパイプがパイプ サーバーの場合、WaitForConnection メソッドを呼び出してクライアント接続を待機します。名前付きパイプがパイプ クライアントの場合、Connect メソッドを呼び出して名前付きパイプ サーバーを待機します。ChannelManager コンストラクターは、接続が確立されるまで制御を戻しません。

    • Dispose メソッド : クラスがスコープ外に出ると、そのインスタンス化されたリソース (Stream m_Stream) を解放して System.IDisposable インターフェイスを実装します。

    • ReadMessage メソッド : パイプ クライアントからのメッセージを受信します。

    • SendMessage メソッド : パイプ クライアントにメッセージを送信します。

  • AppControl メソッド : Alice によって使用され、Bob および Mallory にアプリケーション制御フラグを送信します。これらのフラグにより、3 つのコマンド ウィンドウ間で Version、fMallory、および fVerbose の各状態が同期されます。 AppControl は暗号化またはメッセージ送信には使用されません。アプリケーション間制御のしくみを提供するのみです。このメソッドは、使用後に破棄される一時的な ChannelManager オブジェクトを作成します。

  • SendChannelName メソッド : 新しいチャネル名をクライアントに送信する処理を行う便利なメソッドです。このメソッドは、使用後に破棄される一時的な ChannelManager オブジェクトを作成します。

  • ReceiveChannelName メソッド : 新しいチャネル名をサーバーから受信する処理を行う便利なメソッドです。このメソッドは、使用後に破棄される一時的な ChannelManager オブジェクトを作成します。

ChannelManager クラスの詳細

Alice、Bob、および Mallory の各アプリケーションは、ChannelManager インスタンスによって作成された名前付きパイプで接続されます。各アプリケーションは、2 種類の ChannelManager オブジェクトを作成および破棄します。

  • 長期間のオブジェクト : Alice および Bob の両方で Run メソッド開始時に長期間の ChannelManager オブジェクトを作成します。このオブジェクトを使用して営業情報を送信します。Mallory は、Run メソッドで長期間の ChannelManager オブジェクトを 2 つ作成し、Alice との通信、Bob との通信に 1 つずつ使用します。チャネルは、暗号化キーおよび暗号化メッセージの交換に使用されます。これらは、Run メソッドが終了するまで存続し、その後破棄されます。

  • 一時的なオブジェクト : AppControl、SendChannelName、および ReceiveChannelName の各メソッドは、特定のタスクを実行するために、一時的な ChannelManager オブジェクトを作成します。その後、オブジェクトは破棄されます。また、バージョン 4 およびバージョン 5 では、Alice は、一時的な ChannelManager オブジェクトを使用して Bob にデジタル署名の秘密キーを送信します。

ChannelManager クラスは、System.IDisposable インターフェイスを実装し、send および receive の両方の送信モードを管理します。

このクラスにより、Alice、Bob、および Mallory の間で動的な交換が行われているように見せかけます。実際には、パイプは一度に 1 つのモードにのみ存在します。つまり、サーバー、クライアントのいずれかにのみ存在できます。したがって、Alice、Bob、および Mallory の各アプリケーションは、連続的に周到な方法で実行されます。各アプリケーションでは、例の実行中、特定の時間に開いたり、閉じたりするパイプが必要になります。通信は非同期ではありませんが、非同期のように見えることがあります。

スレッド管理により、バックグラウンドでスレッドを管理しているように見えますが、スレッド呼び出しは行われていません。プロセス間のタイミングは、Alice、Bob、および Mallory の間で send 呼び出しおよび receive 呼び出しのインターリーブを慎重に行うことでのみ実現します。その結果、CNG 例の概要で説明するシナリオに従い、3 つのウィンドウが簡単に通信しているように見えます。

この実装には 1 つの利点として同期があり、そのコードは簡潔で直線的です。欠点としては保全性がないことが挙げられます。パイプ クライアントがサーバーへの接続に失敗した場合、サーバーは応答を停止します。より適切な方法は、マルチスレッド パイプ サーバーを使用することです。マルチスレッド パイプ サーバーはこのようなエラーを適切に処理します。ただし、複雑になるため、例ではこの方法を使用していません。

ChannelManager クラスは、Alice、Bob、および Mallory の各 Main メソッドおよび Communicator.cs ファイルの Communicator クラスのコンストラクターでインスタンス化されます。

使用方法の詳細

ChannelManager クラスは、5 つの異なるコンテキスト (アプリケーション制御、チャネル名送信、メッセージ送信、デジタル署名キー送信、および公開暗号化キー送信) で使用されます。次の一覧では、ソース コードに出現する順にこれらを説明します。

  1. アプリケーション制御 : Alice の Main メソッドの開始時に、Alice によって InitializeOptions メソッドが呼び出され、ユーザーからのセッション オプションが受信されます。その後、これらのオプション (Version、fMallory、および fVerbose) は、AppControl メソッドによって Bob と Mallory に送信されます。ユーザーがアプリケーションを閉じようと「x」の文字を入力すると、AppControl メソッドは、セッション オプションの代わりに「exit」の文字列を Bob と Mallory に送信します。

    • Alice の AppControl メソッドは、一時的な ChannelManager パイプ サーバー、BobControlChannel および MalloryControlChannel の 2 つを作成します。

    • Bob および Mallory の AppControl メソッドは、一時的な ChannelManager パイプ クライアントを作成し、それぞれの制御チャネルに接続します。

    • Bob および Mallory は、Alice からのセッション オプションを受信すると、一時的な ChannelManager オブジェクトを直ちに破棄します。

  2. チャネル名送信 : セッション オプションが送信された後に、Alice から Bob に新しいチャネル名が送信されます。

    • Alice は SendChannelName メソッドを使用し、Bob と Mallory は ReceiveChannelName メソッドを使用します。各メソッドは、一時的な ChannelManager のパイプ サーバーまたはパイプ クライアントを作成します。新しいチャネル名が送信または受信された後に、一時的な ChannelManager インスタンスは破棄されます。

    • Bob が新しいチャネル名を受け取る前の 200 ミリ秒の間に Mallory が ReceiveChannelName を呼び出してそれを傍受すると、セキュリティの欠陥が発生します。このセキュリティの欠陥については、「man-in-the-middle 攻撃の実装 (CNG の例)」を参照してください。

  3. メッセージ送信 : セッション オプションおよび新しいチャネル名が送信された後に、Alice、Bob、および Mallory は Communicator オブジェクトを作成します。Communicator コンストラクターは、前の手順で送信された新しいチャネルの名前を受信し、それを使用して長期間の ChannelManager インスタンスを作成します。これらのオブジェクトは、一時的な ChannelManager インスタンス以外のインスタンスです。これらは、最後のメッセージが送信および受信されるまで存続し、その後破棄されます。

    注意

    Alice によって作成された ChannelManager オブジェクトは、AliceAndBobChannel というパイプ サーバーをカプセル化します。一方で、Mallory がその名前を傍受し、別のチャネル名 (AliceAndBobChannel1) を Bob に送信します。Bob は、この文字列を name パラメーターとして自身の Communicator コンストラクターに渡し、AliceAndBobChannel1 というパイプ クライアントを作成します。この名前変更により、Mallory は Bob へのメッセージでは Alice に偽装することになります。

  4. デジタル署名キー送信 : Alice が自身の Communicator オブジェクトを作成した後に、Version フラグが確認されます。バージョン 3 では、Alice は、PublicChannel 名前付きパイプを介して Bob にデジタル署名キーを送信します。ここで、Mallory がそれを傍受します。バージョン 4 およびバージョン 5 では、Alice は、機密扱いの一時的な ChannelManager インスタンスを作成します。その後、このインスタンスは、デジタル署名の秘密キーを Bob に送信するために使用されます。

    注意

    Mallory は、バージョン 4 またはバージョン 5 のインスタント メッセージング (IM) ソフトウェアを与えられていないため、この非公開の名前付きパイプを把握していません。Alice は手順 3. で作成した、メッセージング用の長期間の ChannelManager オブジェクトを継続使用し、偽のデジタル署名をボブに送信します。バージョン 4 およびバージョン 5 では、Bob の IM ツールがこのオブジェクトを無視するように更新されます。一方で、Mallory はその署名が有効であると思い、自身の暗号化キーおよびメッセージの両方の署名にそれを使用します。これにより、Mallory の偽装が証明されます。

  5. 公開暗号化キー送信 : Version フラグが再度確認されます。バージョン 2 以降では、手順 3. で作成した、メッセージング用の長期間の ChannelManager オブジェクトが公開暗号化キーの送受信に使用されます。

チャネル名、デジタル署名、および暗号化キーが交換された後、Alice と Bob は手順 3. で作成した ChannelManager を使用してメッセージを送信します。

参照

参照

NamedPipeServerStream

NamedPipeClientStream

概念

CNG (Cryptography Next Generation) のセキュリティで保護された通信の例

ChannelManager.cs ソース コード (CNG の例)

ソース コードの概要 (CNG の例)