共用方式為


ChannelManager 類別的程式碼分析 (CNG 範例)

在 Cryptography Next Generation (CNG) 安全通訊範例中,ChannelManager 類別用於提供範例的處理序間通訊 (IPC) 基礎結構。

這個類別負責下列作業:

  • 建立、開啟、關閉和處置具名管道。

  • 傳送和接收應用程式控制旗標、通道名稱、數位簽章、密碼編譯金鑰和訊息。

如需範例概觀和本主題所提及版本的說明,請參閱Cryptography Next Generation (CNG) 安全通訊範例

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 執行個體所建立的具名管道而連接的。每個應用程式會建立和處置兩種類型的 ChannelManager 物件:

  • 長期物件:Alice 和 Bob 在其 Run 方法的開頭,都會建立長期 ChannelManager 物件。他們會使用這個物件傳輸銷售連絡資訊。Mallory 會在其 Run 方法中建立兩個長期 ChannelManager 物件:一個用來與 Alice 通訊,一個用來與 Bob 通訊。這些通道是用來交換密碼編譯金鑰和加密訊息,並會一直保存到 Run 方法的尾端,然後再進行處置。

  • 暫存物件:AppControl、SendChannelName 和 ReceiveChannelName 方法會建立暫存 ChannelManager 物件以執行特定工作,接著再處置這些物件。另外,在版本 4 和 5 中,Alice 會使用暫存 ChannelManager 物件,將私密數位簽章金鑰傳送給 Bob。

ChannelManager 類別會實作 System.IDisposable 介面並管理 send 和 receive 傳輸模式。

類別會帶給您 Alice、Bob 和 Mallory 間動態交換的錯覺。實際上,管道一次只能處於一種模式:不是伺服器就是用戶端。因此,Alice、Bob 和 Mallory 應用程式是謹慎地以線性方式執行的。在範例執行期間,每個應用程式會預期管道會於特定時間開啟和關閉。雖然通訊看起來是非同步的,但實際上不是。

看起來似乎有執行緒管理員在背景管理執行緒,但其實並沒有套用任何執行緒呼叫。處理序間的時間安排僅是透過在 Alice、Bob 和 Mallory 間謹慎插入 send 和 receive 呼叫而達成。結果,這 3 個視窗間的通訊看起來是輕而易舉地,會遵循 CNG 範例概觀中所討論的案例。

這個實作的一個好處是同步處理,而且程式碼很簡單直接,是以線性的方式表達。而一個缺點就是不夠健全:如果管道用戶端連接伺服器時發生錯誤,伺服器將會停止回應。比較好的方法應該是使用多執行緒管道伺服器,該伺服器應該可以更妥善地處理這類錯誤。然而,為了避免過於複雜,本範例沒有採用該措施。

ChannelManager 類別是從 Alice、Bob 和 Mallory 的 Main 方法和 Communicator.cs 檔案的 Communicator 類別建構函式執行個體化的。

用法詳細資料

在 5 個不同情況下會使用到 ChannelManager 類別:應用程式控制、通道名稱傳輸、訊息傳輸、數位簽章金鑰傳輸和公開加密金鑰傳輸。在下列清單中,會以這些情況在原始程式碼中出現的順序進行討論。

  1. 應用程式控制:Alice 會在其 Main 的開頭呼叫 InitializeOptions 方法,並接收使用者的工作階段選項。接著會將這些選項 (Version、fMallory 和 fVerbose) 透過 AppControl 方法傳送給 Bob 和 Mallory。如果使用者決定藉由輸入 "x" 關閉應用程式,AppControl 方法會傳送字串 "exit" 給 Bob 和 Mallory,而非工作階段選項。

    • Alice 的 AppControl 方法會建立兩個暫存的 ChannelManager 管道伺服器:BobControlChannel 和 MalloryControlChannel。

    • Bob 和 Mallory 的 AppControl 方法會建立暫存 ChannelManager 管道用戶端,並連接到其相對的控制通道。

    • Bob 和 Mallory 會接收來自 Alice 的工作階段選項,並立即處置暫存的 ChannelManager 物件。

  2. 通道名稱傳輸:傳輸工作階段選項後,Alice 會傳送新通道名稱給 Bob。

    • Alice 使用 SendChannelName 方法,而 Bob 和 Mallory 使用 ReceiveChannelName 方法。每個方法會建立暫存的 ChannelManager 管道伺服器或用戶端。在傳送或接收新通道名稱後,就會處置暫存的 ChannelManager 執行個體。

    • 當 Mallory 比 Bob 早 200 毫秒呼叫 ReceiveChannelName 而攔截到新通道名稱時,就發生安全性缺陷。如需這個安全性缺陷的討論,請參閱實作攔截式攻擊 (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 中,她會透過已由 Mallory 攔截的 PublicChannel 具名管道,傳送數位簽章金鑰給 Bob。在版本 4 和 5 中,她會建立暫存的秘密 ChannelManager 執行個體。接著會用這個執行個體來傳輸私密數位簽章金鑰給 Bob。

    注意事項注意事項

    Mallory 因為沒有收到即時訊息 (IM) 軟體的版本 4 或 5,所以不知道這個私用具名管道。Alice 會繼續使用步驟 3 中建立的長期傳訊 ChannelManager 物件,將假的數位簽章傳送給 Bob。在版本 4 和 5 中,Bob 的 IM 工具已經更新為忽略這個物件。但 Mallory 認為這個簽章是有效的,並用來簽署他的密碼編譯金鑰和訊息。這就證實他的行跡已敗露。

  5. 公開加密金鑰傳輸:會再度檢查 Version 旗標。在版本 2 (含) 以後,會使用步驟 3 中建立的長期傳訊 ChannelManager 物件來傳送和接收公開加密金鑰。

在交換過通道名稱、數位簽章和密碼編譯金鑰後,Alice 和 Bob 會使用步驟 3 中建立的 ChannelManager 來傳輸訊息。

請參閱

參考

NamedPipeServerStream

NamedPipeClientStream

概念

Cryptography Next Generation (CNG) 安全通訊範例

ChannelManager.cs 原始程式碼 (CNG 範例)

原始程式碼概觀 (CNG 範例)