使用证书

为了对 Windows Communication Foundation (WCF) 安全性进行编程,X.509 数字证书通常用于对客户端和服务器进行身份验证、加密和数字签名消息。 本主题简要介绍了 X.509 数字证书功能以及如何在 WCF 中使用它们,并包含指向进一步解释这些概念的主题的链接,或说明如何使用 WCF 和证书完成常见任务。

简言之,数字证书是 公钥基础结构 (PKI)的一部分,它是数字证书、证书颁发机构和其他注册机构的系统,通过公钥加密来验证和验证电子事务中涉及的每一方的有效性。 证书颁发机构颁发证书,每个证书都有一组字段,其中包含数据,例如 使用者 (颁发证书的实体)、有效期(证书有效时)、颁发者(颁发证书的实体)和公钥。 在 WCF 中,每个属性都作为一个 Claim进行处理,每个声明进一步划分为两种类型:标识和权利。 有关 X.509 证书的详细信息,请参阅 X.509 公钥证书。 有关 WCF 中的声明和授权的详细信息,请参阅 使用标识模型管理声明和授权。 有关实现 PKI 的详细信息,请参阅 使用 Windows Server 2012 R2 Active Directory 证书服务的企业 PKI

证书的主要功能是向其他人验证证书所有者的身份。 证书包含所有者的 公钥 ,而所有者保留私钥。 公钥可用于加密发送到证书所有者的消息。 只有所有者有权访问私钥,因此只有所有者才能解密这些消息。

证书必须由证书颁发机构颁发,该颁发机构通常是证书的第三方颁发者。 在 Windows 域中,包括可用于向域上的计算机颁发证书的证书颁发机构。

查看证书

若要使用证书,通常需要查看证书并检查其属性。 使用 Microsoft 管理控制台 (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 的证书。 根证书颁发机构的证书本质上是被信任的。

数字证书用于通过依赖此层次结构(也称为 信任链)对实体进行身份验证。 可以使用 MMC 管理单元查看任何证书链,方法是双击任何证书,然后单击“ 证书路径 ”选项卡。有关为证书颁发机构导入证书链的详细信息,请参阅 如何:指定用于验证签名的证书颁发机构证书链

注释

通过将颁发者的证书放置在受信任的根颁发机构证书存储中,任何颁发者都可以被认证为受信任的根颁发机构。

禁用链信任

创建新服务时,可能使用的是不由受信任的根证书颁发的证书,或者颁发证书本身可能不在受信任的根证书颁发机构存储中。 出于开发目的,可以暂时禁用检查证书信任链的机制。 为此,请将 CertificateValidationMode 属性设置为或 PeerTrustPeerOrChainTrust。 任一模式都指定证书可以是自颁发(对等信任)或信任链的一部分。 可以在以下任何类上设置属性。

班级 资产
X509ClientCertificateAuthentication X509ClientCertificateAuthentication.CertificateValidationMode
X509PeerCertificateAuthentication X509PeerCertificateAuthentication.CertificateValidationMode
X509ServiceCertificateAuthentication X509ServiceCertificateAuthentication.CertificateValidationMode
IssuedTokenServiceCredential IssuedTokenServiceCredential.CertificateValidationMode

还可以使用配置设置属性。 以下元素用于指定验证模式:

自定义身份验证

CertificateValidationMode 属性还允许自定义证书的身份验证方式。 默认情况下,级别设置为 ChainTrust。 若要使用 Custom 该值,还必须将 CustomCertificateValidatorType 属性设置为用于验证证书的程序集和类型。 若要创建自定义验证程序,必须继承自抽象 X509CertificateValidator 类。

在创建自定义身份验证器时,要重写的最重要方法是 Validate 方法。 有关自定义身份验证的示例,请参阅 X.509 证书验证程序 示例。 有关详细信息,请参阅 自定义凭据和凭据验证

使用 PowerShell New-SelfSignedCertificate cmdlet 生成证书链

PowerShell New-SelfSignedCertificate cmdlet 创建 X.509 证书和私钥/公钥对。 可以将私钥保存到磁盘,然后使用它颁发和签名新证书,从而模拟链接证书的层次结构。 该 cmdlet 仅用于在开发服务时用作辅助,不应用于创建用于实际部署的证书。 开发 WCF 服务时,请使用以下步骤生成与 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.

还可使用 >(属于 >)和 >(属于 >)的 属性在配置中设置模式。

SetCertificate 方法

在 WCF 中,通常必须指定服务或客户端用来对消息进行身份验证、加密或数字签名的证书或证书集。 可以通过使用表示 X.509 证书的各种类的SetCertificate方法来以编程方式实现此操作。 以下类使用 SetCertificate 的方法指定证书。

班级 方法
PeerCredential SetCertificate
X509CertificateInitiatorClientCredential SetCertificate
X509CertificateRecipientServiceCredential SetCertificate
X509CertificateInitiatorServiceCredential
SetCertificate

该方法 SetCertificate 的工作原理是指定存储位置和存储、指定证书字段的“find”类型(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")

具有相同值的多个证书

一个证书存储区可能包含多个具有相同主题名称的证书。 这意味着,如果指定x509FindTypeFindBySubjectNameFindBySubjectDistinguishedName有多个证书具有相同的值,则会引发异常,因为无法区分所需的证书。 可以通过将此设置设置为x509FindTypeFindByThumbprint来缓解此问题。 指纹字段包含可用于在存储中查找特定证书的唯一值。 但是,这有其自身的缺点:如果证书被吊销或续订,则 SetCertificate 方法会失败,因为指纹也消失。 或者,如果证书不再有效,身份验证将失败。 缓解此问题的方法是将 x590FindType 参数 FindByIssuerName 设置为并指定颁发者的名称。 如果不需要特定的颁发者,还可以设置其他 X509FindType 枚举值之一,例如 FindByTimeValid

配置中的证书

还可以使用配置设置证书。 如果您正在创建服务,凭据(包括证书)的指定位置位于 <serviceBehaviors> 之下。 对客户端进行编程时,证书在 endpointBehaviors< 下>指定。

将证书映射到用户帐户

IIS 和 Active Directory 的一项功能是能够将证书映射到 Windows 用户帐户。 有关该功能的详细信息,请参阅 将证书映射到用户帐户

有关使用 Active Directory 映射的详细信息,请参阅 将客户端证书与目录服务映射映射

启用此功能后,可以将类的属性MapClientCertificateToWindowsAccount设置为 X509ClientCertificateAuthenticationtrue。 在配置中,您可以将>元素的属性设置为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 证书不满足域策略,则在第一版下运行正常的早期应用程序,可能会失败。

另请参阅