MSDN 首頁 

建置安全的遠端元件

發佈日期: 2004 年 5 月 28 日
本頁內容
本單元內容本單元內容
目標目標
適用於適用於
如何使用本單元如何使用本單元
概觀概觀
潛在威脅及因應對策潛在威脅及因應對策
設計考量設計考量
輸入驗證輸入驗證
驗證驗證
授權授權
機密資料機密資料
拒絕服務拒絕服務
例外管理例外管理
稽核和記錄稽核和記錄
程式碼存取安全性 (CAS) 考量程式碼存取安全性 (CAS) 考量
總結總結
其他資源其他資源

本單元內容

Microsoft® .NET Framework 遠端作業提供存在於不同應用程式網域 (AppDomains)、不同處理序及不同電腦中的物件豐富且可延伸的架構,使其相互之間完美地溝通。.NET 遠端服務提供功能強大且簡單的程式設計模型及執行階段支援,使這些互動透明化。

雖然遠端服務基礎結構沒有預設的驗證或授權機制,如果您使用 ASP.NET 管理遠端元件並使用 HttpChannel 來通訊,就可以使用 ASP.NET 及 Internet Information Services (IIS) 驗證及授權服務。

本單元包含一些建議及指引,可協助您建立安全的遠端元件。其中包含使用 ASP.NET 及 HttpChannel 的元件,以及使用自訂可執行檔與 TcpChannel 的元件。

回到頁首回到頁首

目標

透過本單元即可:

設計和部署安全的元件。

保障傳遞至遠端元件及由遠端元件傳回的機密資料。

選擇適當的主機處理序。

比較 HttpChannel TcpChannel 的用法。

緩和序列化及 MarshalByRefObject 攻擊的風險。

驗證和授權呼叫者。

防止遠端元件的拒絕服務攻擊。

由於遠端作業元件要求有完全信任,瞭解在部分信任狀況下該如何處理。

瞭解要套用哪個因應對策來指出一般的遠端服務威脅,包括未獲授權的存取、網路竊聽及參數操作。

回到頁首回到頁首

適用於

本單元適用於下列產品及技術:

Microsoft Windows® 2000 Server 及 Microsoft Windows Server™ 2003

Microsoft .NET Framework 1.1 及 ASP.NET 1.1

回到頁首回到頁首

如何使用本單元

若要充分瞭解本單元:

搭配單元 17保障應用程式伺服器的安全>使用。單元 17 提供保障中介層遠端解決方案安全的觀點。

請參閱本指南<檢查清單>一節中的<檢查清單:保障遠端服務的安全>。其中提供建立和設定安全的 .NET Framework 遠端服務方案所需的安全性方法的總結。

回到頁首回到頁首

概觀

Microsoft .NET Framework 遠端服務基礎結構沒有預設的驗證或授權機制。然而,如果您使用 ASP.NET 管理遠端元件,並使用 HttpChannel 通訊,就可以使用 ASP.NET 及 IIS 驗證與授權服務。

如果效能是一項問題,您可能決定使用具有 TcpChannel 的自訂主機。應該只在信任的子系統中才這麼做,因為其中可能的呼叫者範圍會透過 Out-of-band 技術 (例如使用 IPSec 原則) 仔細控制,而這只允許從指定的 Web 伺服器來通訊。使用 TcpChannel 時,您必須建立自己的驗證及授權機制。這與使用試用及測試平台層級的安全性服務的原則相反,而且需要投入大量的開發資源。

本單元提供一些建議及指引,可協助您建立安全的遠端元件。其中包含使用 ASP.NET 及 HttpChannel 的元件,以及使用自訂可執行檔與 TcpChannel 的元件。本單元假設的典型部署形式顯示在 [圖 13.1] 中,其中遠端物件位於中介層應用程式伺服器,並處理來自 ASP.NET Web 應用程式用戶端及部署於企業內部的 Windows 應用程式的要求。

典型的遠端部署

[圖 13.1]
典型的遠端部署

在此常見的案例下,遠端元件會服務來自前端 Web 應用程式的要求。在這種情況下,會由 Web 伺服器上的 ASP.NET 處理呼叫者的驗證及授權。此外,中介層遠端元件通常由企業級 Windows 應用程式存取。

回到頁首回到頁首

潛在威脅及因應對策

若要建立使用遠端技術的安全解決方案,就需要知道相關的潛在威脅。使用遠端技術的元件的首要潛在威脅如下:

未授權存取

網路竊聽

參數操作

序列化

[圖 13.2] 顯示了這些潛在威脅。

主要的遠端潛在威脅

[圖 13.2]
主要的遠端潛在威脅

未授權存取

提供機密性或限制性資訊的遠端元件應該驗證及授權其呼叫者,以防止未獲授權的存取。安全性不足的驗證及授權可能會被利用來取得對機密資訊及作業的未授權存取。

弱點

使遠端解決方案易受未授權存取影響的弱點包括:

由於使用自訂的 Windows 服務主機而沒有應用程式層級的驗證

沒有 IPSec 原則來限制哪部電腦可以與管理遠端元件的中介層應用程式伺服器通訊

沒有角色授權

沒有檔案授權來限制存取遠端端點

從用戶端傳遞的信任 IPrincipal 物件

因應對策

可執行以防止未獲授權存取的因應對策包括:

確定使用 IPSec 原則限制前端 Web 應用程式驗證及授權用戶端,以及中介層應用程式伺服器的通訊。這些方法可確保只有 Web 伺服器可直接存取中介層應用程式伺服器。

使用 ASP.NET 管理遠端元件,並使用 Windows 驗證來限制存取遠端元件。

使用 ASP.NET FileAuthorizationModule。這需要特特殊設定並建立實體檔案 (.rem 或 .soap),以符合遠端端點。

使用角色授權來限制存取遠端元件、遠端元件類別及方法。這可以藉由使用 URL 授權來控制存取遠端端點 (.rem 或 .soap) 而達成,或在類別或方法層級使用主體–權限要求來達成。

不要信任由用戶端傳遞的 IPrincipal 物件,除非信任該用戶端。這通常僅限使用 IPSec 來限制用戶端電腦範圍的狀況。

網路竊聽

利用網路竊聽,攻擊者可在訊息透過網路流動於遠端元件之間時,檢視要求和回應訊息。例如,攻擊者可以使用網路監視軟體來擷取機密資料。這可能包括機密的應用程式層級的資料或憑證資訊。

弱點

因網路竊聽而導致安全性受損的弱點包括:

在未加密的通訊通道上使用基本驗證

傳輸層級未加密

應用程式層級未加密

因應對策

可執行以防止網路竊聽攻擊成功的因應對策包括:

使用傳輸層級加密,例如 SSL 或 IPSec。使用 SSL 需要用到 ASP.NET 主機及 HttpChannel。IPSec 可以搭配自訂主機及 TcpChannel 使用。

在應用程式層級加密要求以提供隱私性。例如,您可以建立自訂加密接收器,以加密整個訊息有效傳輸單元的其中一部份。

參數操作

參數操作是指未獲授權修改用戶端與遠端元件之間傳送的資料。例如,攻擊者可以藉由攔截傳輸中的訊息來處理要送往遠端元件的要求訊息。

弱點

會導致參數操作的弱點包括:

未經數位簽署以防止竄改的訊息

未加密以提供隱私性和防止竄改的訊息

因應對策

可執行以防止參數操作成功的因應對策包括:

數位簽署訊息。在接收端使用數位簽章來確認訊息在傳輸中未遭到竄改。

加密訊息內容以提供隱私性和防止竄改。

序列化

序列化是將物件的內部狀態轉換成平面式位元組資料流的過程。遠端基礎結構使用 .NET Framework 的序列化服務在用戶端與伺服器之間傳遞物件。惡意的程式碼可能將序列化資料流注入伺服器中,迫使它執行非預期的動作。例如,在伺服器還原序列化時,惡意的用戶端程式碼可能會初始化物件,使伺服器消耗伺服器資源或執行惡意程式碼。

弱點

會導致成功序列化攻擊的主要弱點,是源自伺服器信任序列化資料流且無法驗證擷取自資料流的資料的事實。

因應對策

防止成功序列化攻擊的因應對策,是在伺服器還原序列化時要驗證每一個資料項目。驗證每一個欄位的類型、長度、格式和範圍。

回到頁首回到頁首

設計考量

開始開發遠端元件之前,在設計階段時要考慮許多問題。主要的安全性考量如下:

勿在網際網路暴露遠端物件

使用 HttpChannel 來利用 ASP.NET 安全性

只在信任的伺服器情況下使用 TcpChannel

勿在網際網路暴露遠端物件

您應該只主控不可從網際網路直接存取及只能由前端 Web 應用程式及網頁服務存取的中介層應用程式伺服器上的遠端物件。如果需要向網際網路用戶端公開遠端物件提供的功能,請使用 Web 服務來包裝中介層物件,並向網際網路公開 Web 服務。

使用 HttpChannel 來利用 ASP.NET 安全性

如果安全性是您關心的重點,請使用 ASP.NET 來主控遠端物件。如此使您可以利用 ASP.NET 及 IIS 提供的驗證、授權及安全通訊功能。例如,您可以使用 Windows 驗證,並使用 SSL 來提供隱私性及透過網路傳送的要求及回應的完整性。

只在信任的伺服器狀況下使用 TcpChannel

如果基於效能而使用具有自訂主機的 TcpChannel ,請記住內建的驗證服務並不存在。

因此,您應該只在信任的伺服器狀況下使用 TcpChannel,其中上游 Web 應用程式或 Web 服務會在呼叫中介層遠端元件之前驗證及授權原始呼叫者。若要保障此狀況的安全,請使用 IPSec 作為機器層級驗證並保障通訊安全。IPSec 原則應該只允許來自指定 Web 伺服器到中介層遠端元件主機的資料傳輸。這種信任伺服器狀況顯示在 [圖 13.3] 中。

信任的伺服器狀況下的遠端服務

[圖 13.3]
信任的伺服器狀況下的遠端服務

如需有關 IPSec 的詳細資訊,請參閱本指南<How To>一節中的<如何:使用 IPSec>。

TcpChannel 考量

如果使用自訂可執行主機及 TcpChannel,您不可以依賴上游 Web 應用程式來執行用戶端驗證及授權,而必須開發自己的驗證及授權方案。

作為自訂方案的一部份,您可能決定將主體物件當作方法參數或在呼叫內容中傳遞。您應該只在信任的環境中如此做,以防止惡意用戶端程式碼建立具有較高角色的 IPrincipal 物件,然後將它傳送到您的伺服器。您的伺服器實作必須先信任 IPrincipal 物件,再將之用於角色授權。

另一種替代方法是使用執行中的「安全性支援提供者介面 (Security Support Provider Interface,SSPI)」服務。有關此方法的詳細資訊,請參閱 MSDN 文件《.NET Remoting Security Solution, Part 1: Microsoft.Samples.Security.SSPI Assembly (英文)》,此文件位於 http://msdn.microsoft.com/library/en-us/dndotnet/html/remsspi.asp

若要在使用 TcpChannel 時提供安全通訊,請使用 IPSec 或自訂的加密通道接收器來加密要求資料。

回到頁首回到頁首

輸入驗證

在應該使用遠端解決方案的信任伺服器狀況下,前端 Web 應用程式通常會執行輸入驗證。資料會經過完全驗證後,才傳遞到遠端元件。如果您可以保證傳遞到遠端元件的資料只來自現行信任範圍內,就可以讓上游程式碼執行輸入驗證。

不過,如果您的遠端解決方案可供企業中執行的任何用戶端應用程式存取,則遠端元件應該驗證輸入並謹防序列化攻擊及 MarshalByRefObject 攻擊。

序列化攻擊

您可以利用下列其中一種方式將物件參數傳送到遠端元件,使用呼叫內容或透過一般輸入參數將它們傳送到遠端元件所公開的方法中。惡意用戶端可能將物件序列化,然後將它傳遞到遠端元件,以明確意圖操控遠端元件或使它執行未預期的作業。除非您信任用戶端,否則應該小心驗證已序列化物件中的每一個欄位項目,因為物件參數是建立在伺服器上。

MarshalByRefObject 攻擊

衍生自 System.MarshalByRefObject 的物件需要 URL,才可以回呼用戶端。回呼的 URL 有可能會遭到欺騙,使伺服器連線到不同的用戶端電腦,例如防火牆後面的電腦。

使用 .NET Framework 1.1 版,可以減輕序列化和 MarshalByRefObject 攻擊的風險,只要將 <formatter> 元素上的 typeFilterLevel 屬性設定為 Low 即可。如此將指示 .NET Framework 遠端基礎結構只序列化那些為了執行方法呼叫所需的物件,並拒絕任何支援您所建立並放入呼叫內容或當作參數傳遞的序列化的自訂物件。您可以設定 Web.config 中的設定值,或以下所示的程式方式來設定。

<formatter ref="binary" typeFilterLevel="Low" />

或者

BinaryServerFormatterSinkProvider provider = new 
BinaryServerFormatterSinkProvider();
provider.TypeFilterLevel = TypeFilterLevel.Low;
回到頁首回到頁首

驗證

如果您的遠端元件會公開機密資料或作業,就必須驗證其呼叫者以支援授權。.NET Framework 遠端基礎結構並不會定義驗證模型。主機應該處理驗證。例如,您可以使用 ASP.NET 以受益於 ASP.NET 及 IIS 驗證功能。

如果您使用自訂的 Windows 服務主機,則請開發自訂驗證方案。

ASP.NET 主控

若您使用具有 HttpChannel 的 ASP.NET 主機,則適用下列指導方針:

關閉 IIS 中的匿名驗證

設定 ASP.NET 執行 Windows 驗證

設定用戶端憑證

使用驗證連線共用以提升效能

強制用戶端驗證每一個呼叫

控制使用已驗證的連線

關閉 IIS 中的匿名驗證

若要確保呼叫者是由 IIS 驗證,請確定應用程式的虛擬目錄不支援匿名驗證。在 Windows Server 2003 中,您還應該確定停用 .NET Passport 驗證。

由於您已經停用 IIS 匿名驗證,因此可以使用任何支援的 IIS 驗證機制透過 HttpChannel 來驗證呼叫者,例如「基本驗證」、「摘要式驗證」及「整合的 Windows 驗證」。若要避免憑證在網路上傳遞並利用 Windows 2000 安全性帳戶與密碼原則,請使用「整合的 Windows 驗證」。

設定 ASP.NET 執行 Windows 驗證

使用 Web.config 中以下的設定值來設定應用程式執行 Windows 驗證:

<authentication mode="Windows" />

您不可以使用「Passport 驗證」或「表單驗證」,因為這些都需要重新導向到登入頁面。

注意 當您使用 Windows 驗證時,建議啟用「檔案授權」。如需詳細資訊,請參閱本單元稍後的「授權」。

設定用戶端憑證

若要與設定執行 Windows 驗證的遠端元件成功通訊,用戶端必須以要使用的憑證來設定遠端 Proxy,以進行驗證。若未如此做,將產生拒絕存取錯誤。

您可以設定預設的憑證使用用戶端的現行執行緒或處理序權杖,或者設定明確的憑證。

使用預設憑證

若要使用用戶端的處理序權杖 (或執行緒權杖 (如果目前模擬用戶端執行緒)),請將用戶端 Proxy 的 useDefaultCredentials 屬性設定為 true。這會使用戶端收到伺服器的驗證挑戰時使用 CredentialsCache.DefaultCredentials。您可以使用設定檔或撰寫程式來設定 Proxy。若要由外部來設定 Proxy,請在用戶端設定檔中使用下列元素:

<channel ref="http client" useDefaultCredentials="true" />

若要撰寫程式來設定預設憑證,請使用下列程式碼:

IDictionary channelProperties;
channelProperties = ChannelServices.GetChannelSinkProperties(proxy);
channelProperties ["credentials"] = CredentialCache.DefaultCredentials;

若您使用 ASP.NET 用戶端應用程式中設定用於模擬的預設憑證,請使用執行緒層級模擬權杖。這需要 Kerberos 委派。

使用替代憑證

若要在呼叫遠端物件時使用一組特定的憑證來進行驗證,請使用下列設定來停用設定檔中的預設憑證。

<channel ref="http" useDefaultCredentials="false" />

注意 程式設定一定會覆寫設定檔中的設定。

然後使用下列程式碼將 Proxy 設定為使用特定憑證:

IDictionary channelProperties =  
ChannelServices.GetChannelSinkProperties(proxy);
NetworkCredential credentials;
credentials = new NetworkCredential("username", "password", "domain");
ObjRef objectReference = RemotingServices.Marshal(proxy);
Uri objectUri = new Uri(objectReference.URI);
CredentialCache credCache = new CredentialCache();
// Substitute "authenticationType" with "Negotiate", "Basic", "Digest", 
// "Kerberos" or "NTLM"
credCache.Add(objectUri, "authenticationType", credentials);
channelProperties["credentials"] = credCache;
channelProperties["preauthenticate"] = true;

使用驗證連線共用以提升效能

當您設定 useDefaultCredentials="true" 時,也應該將用戶端的 useAuthenticatedConnectionSharing 屬性設定為 true。這可讓伺服器重複使用已驗證的連線,而不是驗證每個連入的呼叫。

<channel ref="http client" useAuthenticatedConnectionSharing="true" >

此功能只能搭配 .NET Framework 1.1 版本的 HttpChannel 使用。

強制用戶端驗證每一個呼叫

unsafeAuthenticatedConnectionSharing 設定為 false,讓用戶端無法提供它們自己的憑證及連線群組名稱給伺服器。

若您將它設定為 true,未經驗證的用戶端就可能使用先前已驗證的用戶端來驗證伺服器。如果 useAuthenticatedConnectionSharing 屬性設定為 true,將忽略此設定。此設定對效能有些許影響,因為它會關閉伺服器的每一個連線,這表示用戶端每次呼叫時都必須驗證。若您使用此設定,也應該指定使用此連線之每個使用者的 ConnectionGroupName

<channel ref="http client" unsafeAuthenticatedConnectionSharing="false" >

此功能只能搭配 .NET Framework 1.1 版本的 HttpChannel 使用。

控制使用已驗證的連線

若您將 unsafeAuthenticationConnectionSharing 設定為 true,就應該設定 connectionGroupName 屬性來提供一個名稱將已驗證的連線群組起來。如果使用預設憑證,connectionGroupName 會以用來執行執行緒的使用者帳戶為基礎。

<channel ref="http client" connectiongroupname="<name>" />

自訂處理序主控

如果使用 Windows 服務主機及 TcpChannel,請只將此方法用於信任的伺服器狀況下,或提供自訂驗證配置。若您使用具有 TcpChannel 的自訂主機,則適用下列指導方針:

請勿在網路上傳遞純文字憑證

請勿信任從用戶端傳遞來的 IPrincipal 物件

請勿在網路上傳遞純文字憑證

如果伺服器要求用戶端的純文字憑證,請在網路上傳遞之前先將它們加密。如果伺服器需要驗證用戶端憑證,請使用挑戰/回應配置來驗證伺服器上的憑證。這應該包含傳送雜湊、金鑰式 (Keyed) 雜湊、使用雜湊加密的 Nonce 或使用數位簽章。

不過,在此狀況下,您應該使用加密的通訊通道來防止重新執行攻擊。

請勿信任從用戶端傳遞來的 IPrincipal 物件

如果將 IPrincipal 物件從用戶端傳遞到伺服器,請小心使用。不信任的程式碼可能會建立 IPrincipal 物件,使用角色將之初始化,然後將它傳送到伺服器。如果伺服器接受 IPrincipal 而未加以驗證,則用戶端可以提高伺服器上呼叫者的權限。例如,惡意呼叫者可以建立 IPrincipal 物件,其中含有通用的高特殊權限角色名稱,例如 Administrators、Managers、ExpenseReportApprovers 及 Supervisors。當伺服器收到物件並將它放入 Thread.CurrentPrincipal 屬性中時,在此物件上呼叫 IsInRole 的程式碼可能會遭到矇騙而執行特殊權限程式碼。

回到頁首回到頁首

授權

在 .NET Framework 遠端服務的內容中,您可以套用授權以限制電腦和使用者存取由遠端物件公開之功能的能力。使用下列指導方針來確保您擁有有效的授權:

使用 IPSec 執行機器層級的存取控制

啟用檔案授權以執行使用者存取控制

以主體為基礎的角色檢查來授權使用者

考慮限制遠端存取

使用 IPSec 執行機器層級的存取控制

您可以定義 IPSec 原則來確保只有指定的 Web 伺服器或伺服器叢集可以連線到管理您的遠端物件的應用程式伺服器。如此可大為降低被攻擊的風險。

啟用檔案授權以執行使用者存取控制

如果您的遠端物件是由 ASP.NET 所主控而且使用的是 Windows 驗證,就可以在遠端端點上設定 Windows 存取控制清單 (ACL) 來授權呼叫者。ACL 是由 ASP.NET FileAuthorizationModule 以每一要求為基礎來評估。在一般狀況下,代表用戶端所連接的遠端端點的實體檔案並不存在。要求具有 .rem 或 .soap 副檔名的檔案,就足以讓 IIS 根據 IIS Metabase 中定義的應用程式對應,將此要求轉送到正確 ASP.NET 應用程式的遠端基礎結構中。

若要設定 .NET Framework Remoting 的 ASP.NET FileAuthorizationModule

1.

在應用程式虛擬目錄的根目錄建立一個與 Web.config 中 objectUri 屬性值同名的檔案,例如 RemoteMath.rem。
您可以從用來設定伺服器遠端物件的 Web.config 取得 objectUri。尋找 <wellknown> 元素,如下列範例所示:

<wellknown mode="SingleCall" objectUri="RemoteMath.rem" 
type="RemotingObjects.RemoteMath, RemotingObjects, 
Version=1.0.000.000 Culture=neutral, PublicKeyToken=4b5ae668c251b606"/>

2.

在檔案最前面加入下列此行,然後儲存檔案。

<%@ webservice class="YourNamespace.YourClass" ... %>

3.

使用 Windows 檔案總管將正確設定的 ACL 加入檔案中,以決定哪些使用者或使用者群組能否存取此物件。

以主體為基礎的角色檢查來授權使用者

您可以使用上述的 FileAuthorizationModule 方法來控制可或不可存取遠端物件的對象。如需可套用到方法層級的更細微授權,可以使用附加於目前要求的 IPrincipal 物件來執行授權檢查。

如果遠端物件是由 ASP.NET 所管理而且使用的是 Windows 驗證,則會自動建立以已驗證的呼叫者 Windows 識別身份為基礎的 IPrincipal 物件,然後附加到 Thread.CurrentPrinicipal

若您是使用自訂主機,請建立 IPrincipal 物件以代表已驗證的使用者。此技術取決於您的驗證方法。例如,如果使用具名管道傳輸,就可以模擬呼叫者來取得其識別身份並建構 IPrincipal 物件。

建有 IPrincipal 物件後,您就可以使用敘述性和命令性的主體權限要求來執行授權,而且可以呼叫 IPrincipal.IsInRole

考慮限制遠端存取

在使用遠端服務作為單一電腦上處理序之間或跨應用程式網域通訊的某些狀況下,可以將 rejectRemoteRequests 設定為 true,以確保從遠端電腦無法存取您的物件,如下所示。

<channel ref="http server" rejectRemoteRequests="true" />
回到頁首回到頁首

機密資料

如果需要透過遠端通訊通道跨網路來傳遞機密資料,以解決網路竊聽的潛在威脅,請考慮資料的隱私性及完整性。您有三個基本選擇,可由部署環境及主機選擇來決定。這些選項包含:

使用 IPSec

使用 SSL

使用自訂加密接收器

使用 IPSec

您可以使用 IPSec 原則來保障遠端物件通訊通道的安全,例如,來自 Web 伺服器的通道。可以使用 IPSec 加密透過特殊連線傳送的所有 TCP 封包,其中包括從遠端物件來回傳送的封包。此解決方案通常由安全網際網路及內部網路資料中心基礎結構所使用,而且非常有利,因為不需要額外的編碼工作。

使用 IPSec 的額外好處是提供一套不管遠端物件主機及通道類型為何的安全通訊方案。例如,在使用 TcpChannel 及自訂主機時,就可以使用此方案。

使用 SSL

若您使用 ASP.NET 主機,可以使用 IIS 將應用程式的虛擬目錄設定為要求 SSL。用戶端後續就必須使用 HTTPS 連線與遠端物件通訊。

使用自訂加密接收器

若您沒有具 IPSec 原則的安全資料中心來保障伺服器之間通訊通道的安全,替代的策略是執行自訂加密接收器。如果您只需要保障從用戶端傳送到伺服器的訊息中機密部分的安全,而不是整體內容的安全,則可能也會想要考慮這個選項。此方法顯示在 [圖 13.4] 中。

使用自訂加密接收器

[圖 13.4]
使用自訂加密接收器

加密接收器是自訂的接收器,可在您使用具有 TcpChannel 的自訂主機時使用。在用戶端,接收器會在將要求的資料傳送到伺服器之前予以加密,然後解密從伺服器收到的任何已加密回應資料。在伺服器端,接收器會解密要求的資料,然後加密回應資料。

使用自訂加密接收器

接收器應該使用非對稱加密來交換工作階段層級的加密金鑰。交換工作階段金鑰之後,用戶端和伺服器會保存一份金鑰,而任一端都可以在通道接收器存留期隨時選擇建立新金鑰。伺服器應該對與它通訊的每一個用戶端保存不同的金鑰。

下列步驟概述執行自訂加密接收器的基本方法:

1.

建立解決方案的公開/私密金鑰組。

const int AT_KEYEXCHANGE =  1;
CspParameters cspParams = new CspParameters();
cspParams.KeyContainerName = "<container name>";
cspParams.KeyNumber = AT_KEYEXCHANGE;
cspParams.ProviderName = "Microsoft Base Cryptographic Provider v1.0";
cspParams.ProviderType = PROV_RSA_FULL;
RSACryptoServiceProvider rsaServerSide = new 
RSACryptoServiceProvider(cspParams);
rsaServerSide.PersistKeyInCsp = true;
Console.WriteLine(rsaServerSide.ToXmlString(true)); // 寫入公開金鑰

2.

顯示公開金鑰供用戶端使用。
用戶端會在檔案中保存一份公開金鑰。

3.

初始化用戶端通道接收器,然後建立用來加密的隨機金鑰。

byte[] randomKey = new byte[size];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(randomKey);

4.

使用伺服器的公開金鑰來加密隨機金鑰。使用 IClientChannelSink.ProcessMessage 將已加密的金鑰傳送到伺服器。

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp);
rsa.FromXmlString("<server's public key>");
AsymmetricKeyExchangeFormatter formatter = new 
RSAPKCS1KeyExchangeFormatter(rsa);
byte[] encryptedSessionKey =  formatter.CreateKeyExchange(_sessionKey);

5.

初始化伺服器通道接收器,並使用特定金鑰容器名稱建立 RSA 物件。

const int AT_KEYEXCHANGE =  1;
CspParameters cspParams = new CspParameters();
cspParams.KeyContainerName = "<container name>";
cspParams.KeyNumber = AT_KEYEXCHANGE;
cspParams.ProviderName = "Microsoft Base Cryptographic Provider v1.0";
cspParams.ProviderType = PROV_RSA_FULL;
RSACryptoServiceProvider rsaServerSide = new 
RSACryptoServiceProvider(cspParams);

6.

從用戶端擷取已加密的金鑰。此金鑰通常會在要求標頭中傳送。

7.

使用伺服器的私密金鑰來解密工作階段加密金鑰。

AsymmetricKeyExchangeDeformatter asymDeformatter = new 
RSAPKCS1KeyExchangeDeformatter(_rsa);
byte[] decryptedSessionKey =  asymDeformatter.DecryptKeyExchange(
<encrypted key>);

8.

使用對應用戶端到加密金鑰的機制,例如使用雜湊資料表。

此時,用戶端和伺服器會共用加密金鑰,而且可以加密和解密方法呼叫。在物件存留期間,可以且應該週期性地建立新金鑰。

回到頁首回到頁首

拒絕服務

當惡意用戶端建立多重物件並繼續更新存留期租用以消耗伺服器資源時,就會發生拒絕服務攻擊。伺服器端遠端物件包含預設租用。在此狀態下,用戶端可以永遠繼續更新租用。不過,您可以執行伺服器上的 ILease 介面,然後明確控制贊助者及更新。若要這麼做,請覆寫 MarshalByRefObject 物件上的 InitializeLifetimeService 。遠端基礎結構會在建立物件時呼叫此方法。同樣可以使用 <lifetime> 元素以程式的方式來設定租用。

回到頁首回到頁首

例外管理

確定您未將完整例外狀況傳回給呼叫者。若您使用 ASP.NET 主機,請確定已經設定 ASP.NET,以傳回一般性錯誤訊息給用戶端,如下所示。

<configuration>
<system.runtime.remoting>
<!-- 模式屬性的有效值包括
開啟 - 呼叫者接收預設錯誤訊息
僅限遠端 - 與遠端元件用來接收
詳細例外狀況資訊的同一部電腦上的用戶端。遠端呼叫接收
預設錯誤訊息
關閉 - 呼叫者接收詳細的例外狀況資訊 -->
<customErrors mode="on"/>
</system.runtime.remoting>
</configuration>

使用 mode="on" mode="remoteOnly"。請勿在產品伺服器上使用 mode="off"

使用自訂通道接收器

您可以執行自訂通道接收器,以執行用戶端及/或伺服器端的例外狀況記錄。如果發生例外狀況,可以在 SyncProcessMessageProcessMessageSyncProcessMessage 方法中記錄例外狀況詳細資訊。IMessage Exception 參數提供例外狀況詳細資訊。

回到頁首回到頁首

稽核和記錄

若您使用 ASP.NET 主機,就可以使用 IIS 稽核功能。如果使用自訂主機,請執行自訂稽核。若要這麼做,您可以執行自訂通道接收器。

使用自訂通道接收器

您可以執行自訂通道接收器,以執行用戶端及/或伺服器端的稽核。可以從 SyncProcessMessageProcessMessageSyncProcessMessage 方法中取得詳細資訊。

回到頁首回到頁首

程式碼存取安全性 (CAS) 考量

在 .NET Framework 版本 1.0 和 1.1 上,遠端服務用戶端需要有完全信任。System.Runtime.Remoting.dll 組件並未以 AllowPartiallyTrustedCallersAttribute 標記。

若要使用遠端服務從部分信任程式碼呼叫遠端元件,例如部分信任 Web 應用程式,您必須建立完全信任包裝函式組件及遠端物件方法呼叫的沙箱 (sandbox)。如需有關建立程式碼沙箱及使用包裝函式組件的詳細資訊,請參閱單元 9<配合 ASP.NET 使用程式碼存取安全性>。

回到頁首回到頁首

總結

.NET Framework 遠端服務基礎結構是設計用於受信任的伺服器,您可在此限制呼叫者為受信任的用戶端,例如使用 IPSec 安全性原則。如果使用 ASP.NET 主機及 HttpChannel,就能受益於使用 ASP.NET 及 IIS 提供的基礎安全性功能。如果使用自訂主機及 TcpChannel,或許基於效能考量,您必須執行自己的驗證與授權方案。IPSec 可藉由提供機器層級的驗證與安全的通訊,對這些狀況提供一些助益。

回到頁首回到頁首

其他資源

有關其他詳細資訊,請參閱下列資源:

如需可列印的檢查清單,請參閱本指南<檢查清單>一節中的<檢查清單:保障遠端服務的安全>。

如需有關如何管理 Windows 服務中的遠端元件的詳細資訊,請參閱Microsoft《Patterns & Practices (英文)》第一冊,《建置安全的 ASP.NET Web 應用程式:驗證、授權和安全通訊》中<How to>章節的<How To:在 Windows 服務中裝載遠端物件>一節,此文件位於 http://www.microsoft.com/taiwan/msdn/books/ataglance/SecNetHT15.htm

如需有關如何建立使用 SSPI 的自訂驗證方案的詳細資訊,請參閱 MSDN 文件《.NET Remoting Security Solution, Part 1: Microsoft.Samples.Security.SSPI Assembly (英文)》,此文件位於 http://msdn.microsoft.com/library/en-us/dndotnet/html/remsspi.asp

注意 此文件中的實作是一個範例,並非 Microsoft 所測試和支援的產品。


回到頁首回到頁首