如何在 Windows Server 2016 上使用“客户端身份验证颁发者”证书存储

如何在 Windows Server 2016 上使用“客户端身份验证颁发者”证书存储

问题:

我们有一个在 Windows Server 2016 服务器(服务器核心)上的 IIS 上运行的网站。

在 IIS 中为网站启用了客户端证书身份验证。当检查到该站点的 TLS 连接流量(使用 wireshark)时,我们会看到一条“客户端请求 (13)”消息,该消息将“受信任的颁发者”列表传达给浏览器。该列表当前包含“受信任的根证书颁发机构”存储中的所有证书(证书“预期用途”与客户端身份验证兼容)。

我们希望列表只包含我们选择的单个根证书(这恰好是Origo 根证书但我不认为这与问题相关)。

为了实现这一点,我们将 Origo 根证书放在“客户端身份验证颁发者”存储中,如本文所述:

TLS - SSL (Schannel SSP) 概述

该证书也存在于“受信任的根证书颁发机构”存储中,因此在本地计算机上受到信任。

注意。我们还设置了此注册表项(如上文所述),以便将“受信任的发行者列表”发送到浏览器:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\SendTrustedIssuers = 1 (DWORD)

服务器继续发送来自“受信任的根证书颁发机构”存储的完整证书列表。服务器已重新启动。

我已确认 origo 证书被服务器报告为“受信任”。Windows CAPI2 事件日志中没有与此证书相关的错误,如下所示:

Application and Services Logs\Microsoft\Windows\CAPI2

systeminfo.exe 报告的 Windows 版本信息

OS Name:                   Microsoft Windows Server 2016 Standard
OS Version:                10.0.14393 N/A Build 14393

(已安装所有可用的 Windows 更新)

答案1

我们最终成功了。步骤从上到下依次为:

创建以下注册表项:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\SendTrustedIssuerList = 1 (DWORD)

这是 Windows Server 2012 的要求,请参阅TLS - SSL (Schannel SSP) 概述。请注意,IIS 需要重新启动才能使此设置的更改生效。

如果没有此设置,“可信发行者提供商”列表将始终为空。

除此之外,网站的 netsh 配置必须正确。例如,这是我们当前运行的用于在内部 Web 服务器上配置 https 的 netsh 命令(已替换 ID):

netsh http update sslcert hostnameport=mainintegration.qa.focus-internal.co.uk:443 appid="{app-guid}" certhash={certificate-thumbprint} certstorename=WebHosting sslctlstorename=ClientAuthIssuer

指纹是指用于 https 的服务器端 SSL 证书。有一次,SSL 证书被续订,因此有一个新的指纹,但此命令没有使用新指纹重新运行。相反,IIS UI 用于选择新的 SSL 证书,这可能导致此命令中的额外配置位被删除。具体来说:

sslctlstorename=ClientAuthIssuer

上述文档“TLS 概述 - SSL(Schannel SSP)”链接表示默认使用 ClientAuthIssuer 存储(在证书管理器 UI 中显示为“客户端身份验证颁发者”),但我们发现事实并非如此,需要明确引用该存储,如上所述。

还要注意“netsh http update sslcert”命令。

Netsh http 命令

客户认证谈判 指定是否启用或禁用证书协商。默认为禁用。

我们发现,不仅客户端证书协商会在此设置下发生已禁用,我们的网络应用实际上需要禁用它。这是因为我们的 Web 应用程序依赖于执行 https 重新协商(在应用程序内的特定 URL 上使用客户端证书,而不是整个网站)。这可能并不典型,因此请注意设置名称有点误导。

什么时候需要将“协商客户端证书”设置为启用?

IIS 有两种方式协商 TLS:

  • 客户端在初始请求中发送客户端证书。当服务器上的所有资源都需要 TLS 客户端身份验证时,这很有用。
  • 客户端不会在初始请求中发送客户端,而是在 IIS 执行 TLS 重新协商后发送。当只有部分资源需要 TLS 客户端身份验证时,这很有用。

协商客户端证书设置决定使用哪个,如果启用则使用第一个,如果禁用则使用第二个。以下是 Microsoft 博客中的更多信息(使用 Active Directory 在 IIS 上激活客户端证书映射需要进行的完整更改列表):

如果启用此设置,则在协商与 Web 服务器的初始安全连接时,客户端浏览器将发送客户端证书。

如果禁用它,则将根据服务器证书在 Web 服务器和浏览器之间协商初始安全连接,然后在我们的 Web 应用程序中需要(或实际上请求)客户端证书的特定 URL 上重新协商连接。

因此,启用此设置实际上防止我们所依赖的 https 重新协商,禁用它实际上并不能阻止客户端证书协商!

但请注意,随着 http2 的使用增加,这种重新协商方法可能会再次出现问题,此时我们可能会转向为整个站点启用客户端证书协商。

其他注意事项

netsh http show sslcert可用于转储当前 https 配置以检查其是否符合预期。显示的设置(我认为)存储在注册表中,如下所示:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters\SslBindingInfo\

使用 Wireshark 检查 https 协商需要将浏览器配置为将 SSL 密钥转储到磁盘,并将 Wireshark 配置为查找这些密钥并使用它们解密流量。有关如何执行此操作的详细信息如下:

https://wiki.wireshark.org/TLS#TLS_Decryption

我使用了 [使用每个会话机密的密钥日志文件 (#Using_the_.28Pre.29-Master-Secret)] 方法,因为它不需要访问 ssl 证书私钥(我无权访问)。

相关内容