使用憑證

在針對 Windows Communication Foundation (WCF) 安全性設計程式時,通常會採用 X.509 數位憑證來驗證用戶端與伺服器、加密,以及數位簽署訊息。 本主題將簡要說明 X.509 數位憑證功能及如何在 WCF 中使用這些憑證,同時針對這些概念的進一步說明以及如何運用 WCF 與憑證來完成一般工作的主題說明提供連結。

簡單地說,數位憑證是「公開金鑰基礎結構」(Public Key Infrastructure,PKI) 的一部分,這是一套結合數位憑證、憑證授權單位,與其他登錄授權單位,並以公開金鑰密碼編譯法來驗證參與電子異動每一方之有效性的系統。 憑證授權單位會發出憑證,而每個憑證都會有一組欄位,其中包含如「主體」(也就是接受發行憑證的實體)、有效日期 (當憑證有效時)、簽發者 (發行憑證的實體) 與公開金鑰之類的資料。 在 WCF 中,每一個屬性都會被當成 Claim 處理,而且每個宣告還會進一步分成兩種類型:身分識別與權限。 如需 X.509 憑證的詳細資訊,請參閱 X.509 公用金鑰憑證。 如需宣告和 WCF 授權的詳細資訊,請參閱使用身分識別模型來管理宣告與授權。 如需有關如何執行 PKI 的詳細資訊,請參閱 使用 Windows Server 2012 R2 的企業 PKI Active Directory 憑證服務

憑證的主要功能就是向其他人驗證憑證擁有者的身分識別。 憑證包含擁有者的「公開金鑰」,而擁有者本身則保留私密金鑰。 公開金鑰可以用來加密傳送給憑證擁有者的訊息。 只有擁有者才能存取私密金鑰,因此只有擁有者可以解密這些訊息。

憑證必須由憑證授權單位發行,此單位通常是憑證的協力廠商簽發者。 在 Windows 網域中,會包含憑證授權單位以便用來對網域中的電腦發行憑證。

檢視憑證

使用憑證時,通常需要檢視並檢查其內容。 您可以透過 Microsoft Management Console (MMC) 嵌入式管理單元工具輕鬆達到這個目的。 如需詳細資訊,請參閱 做法:使用 MMC 嵌入式管理單元檢視憑證

憑證存放區

您可以在存放區中找到憑證。 兩個主要的存放區位置還可進一步細分為子存放區。 如果您是電腦的系統管理員,就可以使用 MMC 嵌入式管理單元工具來同時檢視兩個主要的存放區。 非系統管理員只能檢視目前使用者的存放區。

  • 本機電腦存放區。 這包含電腦進程所存取的憑證,例如 ASP.NET。 請使用此位置來存放可對用戶端驗證伺服器的憑證。

  • 目前使用者的存放區。 一般來說,互動性應用程式會將電腦目前使用者的憑證放在此處。 如果您正在建立用戶端應用程式,通常會將用來向服務驗證使用者的憑證放在此處。

這兩個存放區還可進一步細分為子存放區。 使用 WCF 來設計程式時,其中最重要的存放區為:

  • 可信任的根憑證授權單位。 您可以使用此存放區中的憑證來建立憑證鏈結,並藉由這些憑證回溯追蹤到此存放區中某個憑證授權單位的憑證。

    重要

    本機電腦會隱含地信任放在此存放區中的任何憑證,就算此憑證並未來自受信任的協力廠商憑證授權單位也是一樣。 因此,除非您充分信任簽發者並了解其相關影響,否則請勿將任何憑證放在此存放區。

  • 個人。 此存放區可用來存放與電腦使用者相關聯的憑證。 一般來說,此存放區是用來存放 [受信任的根憑證授權單位] 存放區中所找到的其中一個憑證授權單位所發行的憑證。 另外,此處找到的憑證可能是自動發行並由某個應用程式所信任。

如需憑證存放區的詳細資訊,請參閱憑證存放區

選取存放區

選取存放憑證的位置時,必須考量服務或用戶端執行的方式與時機, 並套用下列一般規則:

  • 如果 WCF 服務是裝載在 Windows 服務中,請使用 [本機電腦] 存放區。 請注意,您需要系統管理員權限將憑證安裝到本機電腦存放區。

  • 如果服務或用戶端是透過使用者帳戶執行的應用程式,則請使用 [目前使用者] 存放區。

存取存放區

存放區會受到存取控制清單 (ACL) 的保護,就像電腦上的資料夾一樣。 當您建立由 Internet Information Services (IIS) 所裝載的服務時,ASP.NET 進程會在 ASP.NET 帳戶下執行。 該帳戶必須能夠存取包含服務所使用之憑證的存放區。 每一個主要存放區都會以預設的存取清單加以保護,但是您可以修改此清單。 如果您建立個別的角色來存取存放區,則必須授予該角色存取權限。 若要了解如何使用 WinHttpCertConfig.exe 工具來修改存取清單,請參閱如何:建立開發時要使用的暫時憑證

鏈結信任與憑證授權單位

憑證是在階層中建立的,其中每個個別憑證都會連結到核發憑證的 CA。 此連結連至 CA 的憑證。 CA 的憑證接著會連結到發出原始 CA 憑證的 CA。 在找到根 CA 的憑證之前,會一直重複這個程序。 根 CA 的憑證在本質上會受到信任。

數位簽章會藉由依賴此階層 (也稱為「信任鏈結」來驗證實體。 只要按兩下任何憑證,然後按一下 [ 憑證路徑 ] 索引標籤,就可以使用 MMC 嵌入式管理單元來查看任何憑證的鏈。如需匯入憑證授權單位單位之憑證鏈的詳細資訊,請參閱 如何:指定用來驗證簽章的憑證授權單位單位憑證鏈

注意

您可以藉由將簽發者的憑證放在信任的根授權憑證存放區,為任何簽發者都指定一個信任的根授權。

停用鏈結信任

在建立新服務時,您可能使用並非由信任的根憑證所發行的憑證,或者發行的憑證本身並非位於 [受信任的根憑證授權單位] 存放區中。 如果只是做為開發用途,您可以暫時停用檢查憑證之信任鏈結的機制。 若要這麼做,請將 CertificateValidationMode 屬性 (Property) 設為 PeerTrustPeerOrChainTrust。 每種模式都會將憑證指定為自動發行 (對等信任) 或是信任鏈結的一部分。 您可以在下列任何一個類別中設定屬性。

類別 屬性
X509ClientCertificateAuthentication X509ClientCertificateAuthentication.CertificateValidationMode
X509PeerCertificateAuthentication X509PeerCertificateAuthentication.CertificateValidationMode
X509ServiceCertificateAuthentication X509ServiceCertificateAuthentication.CertificateValidationMode
IssuedTokenServiceCredential IssuedTokenServiceCredential.CertificateValidationMode

您也可以使用組態來設定屬性。 下列項目可用來指定驗證模式:

自訂驗證

CertificateValidationMode 屬性同時可讓您自訂憑證的驗證方式。 根據預設,層級會設為 ChainTrust。 若要使用 Custom 值,您必須同時將 CustomCertificateValidatorType 屬性 (Attribute) 設為可用來驗證憑證的組件與型別。 若要建立自訂驗證程式,您必須繼承自抽象 X509CertificateValidator 類別。

在建立自訂的驗證器時,要覆寫之最重要的方法是 Validate 方法。 如需自訂驗證的範例,請參閱 X.509 憑證驗證程式範例。 如需詳細資訊,請參閱自訂認證與認證驗證

使用 PowerShell New-SelfSignedCertificate Cmdlet 來建立憑證鏈

PowerShell New-SelfSignedCertificate Cmdlet 會建立 x.509 憑證和私用金鑰/公開金鑰組。 您可以將私密金鑰儲存到磁碟,然後用它來發行並簽署新的憑證,藉此模擬鏈結憑證的階層架構。 在開發服務時,此 Cmdlet 僅供用來作為輔助工具,不應該用來建立實際部署的憑證。 開發 WCF 服務時,請使用下列步驟來建立與 New-SelfSignedCertificate Cmdlet 之間的信任鏈。

使用 New-SelfSignedCertificate Cmdlet 建立信任鏈

  1. 使用 New-SelfSignedCertificate Cmdlet 建立暫時的根授權 (自我簽署的) 憑證。 將私密金鑰儲存到磁碟。

  2. 使用新的憑證來發行另一個包含公開金鑰的憑證。

  3. 將根授權憑證匯入 [受信任的根憑證授權單位] 存放區。

  4. 如需逐步教學說明,請參閱如何:建立開發時要使用的暫時憑證

該使用哪個憑證?

關於憑證常見的問題包括該使用哪些憑證以及為何使用這些憑證。 答案需視您是要針對用戶端或服務設計程式而定。 下列資訊將提供您一般性的指示,可能無法完全解答這些問題。

服務憑證

服務憑證的主要工作就是對用戶端驗證伺服器。 當用戶端驗證伺服器時,首先要執行的檢查項目之一就是將 [主體] 欄位的值與用來連絡服務的統一資源識別元 (URI) 加以比較:兩者的 DNS 必須相符。 例如,如果服務的 URI 是,主旨 http://www.contoso.com/endpoint/ 欄位也必須包含值 www.contoso.com

請注意,該欄位可以包含數個值,每個值都可加上代表該值的初始化前置詞。 最常見的情況是,一般名稱的初始化為 "CN",例如 CN = www.contoso.com 。 您也可以將 [主體] 欄位留空,在這種情況下,[主體別名] 欄位則可包含 [DNS 名稱] 值。

另請注意,憑證的 [使用目的] 欄位值應該包含適當的值,例如 [伺服器驗證] 或 [用戶端驗證]。

用戶端憑證

用戶端憑證通常不是由協力廠商憑證授權單位所發行。 反之,目前使用者位置上的 [個人] 存放區通常包含了由根授權所放置、帶有 [用戶端驗證] 使用目的之憑證。 用戶端可以在需要相互驗證時使用這類憑證。

線上撤銷與離線撤銷

憑證有效性

每個憑證只有在指定期間 (稱為「有效期間」) 才有效。 X.509 憑證的 [有效期自] 與 [有效期到] 欄位會定義有效期間。 在驗證期間,會檢查憑證以判斷憑證日期是否仍在有效期間內。

憑證撤銷清單

在有效期間內,憑證授權單位隨時可撤銷憑證。 有許多原因會導致發生這種情況,例如憑證的私密金鑰遭到破壞。

一旦發生這種情況,任何來自已撤銷憑證的鏈結會同時失效,而且在驗證程序期間將不會受到信任。 為了找出已撤銷的憑證,每個簽發者會發佈一個包含時間與日期戳記的「憑證撤銷清單」(CRL)。 您也可以透過將下列類別的 RevocationModeDefaultRevocationMode 屬性設為其中一個 X509RevocationMode 列舉值的方式,使用線上撤銷或離線撤銷來檢查此清單:X509ClientCertificateAuthenticationX509PeerCertificateAuthenticationX509ServiceCertificateAuthenticationIssuedTokenServiceCredential 類別。 所有屬性的預設值為 Online

您也可以使用 revocationMode <authentication>) 的 (<serviceBehaviors><authentication>) (的屬性來設定 configuration 中的模式 <endpointBehaviors>

SetCertificate 方法

在 WCF 中,您必須經常指定服務或用戶端用來驗證、加密或數位簽署訊息的憑證或憑證集。 您也可以使用代表 X.509 憑證之各種類別的 SetCertificate 方法,以程式設計方式來執行這項工作。 下列類別會使用 SetCertificate 方法來指定憑證。

類別 方法
PeerCredential SetCertificate
X509CertificateInitiatorClientCredential SetCertificate
X509CertificateRecipientServiceCredential SetCertificate
X509CertificateInitiatorServiceCredential
SetCertificate

SetCertificate 方法會藉由指定下列項目來進行運作:指定存放區位置與存放區、用來指定憑證欄位的 [尋找] 型別 (x509FindType 參數),以及指定要在欄位中尋找的值。 例如,下列程式碼會建立 ServiceHost 執行個體,並使用 SetCertificate 方法來設定用來向用戶端驗證服務的服務憑證。

Uri baseAddress = new Uri("http://cohowinery.com/services");
ServiceHost sh = new ServiceHost(typeof(CalculatorService), baseAddress );
sh.Credentials.ServiceCertificate.SetCertificate(
StoreLocation.LocalMachine, StoreName.My,
X509FindType.FindBySubjectName, "cohowinery.com");
Dim baseAddress As New Uri("http://cohowinery.com/services")
Dim sh As New ServiceHost(GetType(CalculatorService), baseAddress)
sh.Credentials.ServiceCertificate.SetCertificate( _
StoreLocation.LocalMachine, StoreName.My, _
X509FindType.FindBySubjectName, "cohowinery.com")

使用相同值的多個憑證

存放區可能包含使用相同主體名稱的多個憑證。 也就是說,如果您將 x509FindType 指定為 FindBySubjectNameFindBySubjectDistinguishedName,而且有一個以上的憑證使用相同值,則會因為無法區分所需的憑證是哪一個而擲回例外狀況。 您可以將 x509FindType 設為 FindByThumbprint 來降低此行為的影響。 指紋欄位包含可用來尋找存放區中特定憑證的唯一值。 然而,此欄位也有缺點:如果憑證遭到撤銷或更新,則 SetCertificate 方法會因為指紋一併消失而失敗。 或者,當憑證失效時,驗證也會失敗。 降低這項風險的做法就是,將 x590FindType 參數設為 FindByIssuerName 並指定簽發者名稱。 如果不需要特定的簽發者,則您也可以設定其他任何一個 X509FindType 列舉值,例如 FindByTimeValid

組態中的憑證

您也可以使用組態來設定憑證。 如果您正在建立服務,則會在底下指定認證(包括憑證) <serviceBehaviors> 。 當您設計用戶端時,會在下指定憑證 <endpointBehaviors>

將憑證對應至使用者帳戶

IIS 與 Active Directory 的其中一項功能,就是能夠將憑證對應至 Windows 使用者帳戶。 如需功能的詳細資訊,請參閱將憑證對應至使用者帳戶

如需使用 Active Directory 對應的詳細資訊,請參閱將用戶端憑證與目錄服務進行對應

一旦您啟用這項功能,就可以將 MapClientCertificateToWindowsAccount 類別的 X509ClientCertificateAuthentication 屬性設為 true。 在設定中,您可以將 mapClientCertificateToWindowsAccount 元素的屬性設定 <authentication>true ,如下列程式碼所示。

<serviceBehaviors>
 <behavior name="MappingBehavior">
  <serviceCredentials>
   <clientCertificate>
    <authentication certificateValidationMode="None" mapClientCertificateToWindowsAccount="true" />
   </clientCertificate>
  </serviceCredentials>
 </behavior>
</serviceBehaviors>

將 X.509 憑證對應至代表 Windows 使用者帳戶的權杖可視為權限的提升,因為一旦對應之後,就可以使用 Windows 權杖針對受保護的資源取得其存取權限。 因此,網域原則要求 X.509 憑證在執行對應之前必須先符合此原則規定。 SChannel 安全性套件會強制執行此要求。

使用 .NET Framework 3.5 或更新版本時,WCF 會確保憑證符合網域原則,然後才會對應至 Windows 帳戶。

在第一版的 WCF 中,您不需要諮詢網域原則便可進行對應。 因此,當啟用對應功能且 X.509 憑證無法滿足網域原則要求時,以往在第一版中能夠順利執行的舊版應用程式可能會無法執行。

另請參閱