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

red*_*alx 5 windows ssl

问题:

我们有一个在 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)
Run Code Online (Sandbox Code Playgroud)

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

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

Application and Services Logs\Microsoft\Windows\CAPI2
Run Code Online (Sandbox Code Playgroud)

systeminfo.exe 报告的 Windows 版本信息

OS Name:                   Microsoft Windows Server 2016 Standard
OS Version:                10.0.14393 N/A Build 14393
Run Code Online (Sandbox Code Playgroud)

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

red*_*alx 4

我们最终成功了。从顶部开始的步骤是:

\n

创建以下注册表项:

\n

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

\n

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

\n

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

\n

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

\n

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

\n

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

\n

sslctlstorename=ClientAuthIssuer

\n

上面的文档“Overview of TLS - SSL (Schannel SSP)”链接表示默认使用 ClientAuthIssuer 存储(在证书管理器 UI 中显示为“客户端身份验证颁发者”),但我们发现这不是如果是这种情况,则需要明确引用该商店,如上所述。

\n

另请注意“netsh http update sslcert”命令。

\n

来自Netsh http 命令

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

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

\n

何时需要将\xe2\x80\x9c协商客户端证书\xe2\x80\x9d设置为启用?:

\n
\n

IIS 有两种协商 TLS 的方法:

\n
    \n
  • 客户端在初始请求中发送客户端证书的位置。当服务器上的所有资源都需要 TLS 客户端身份验证时,这非常有用。
  • \n
  • 其中客户端不会在初始请求中向客户端发送,而是在 IIS 执行 TLS 重新协商之后发送。当只有某些资源需要 TLS 客户端身份验证时,这非常有用。
  • \n
\n

“协商客户端证书”设置确定使用哪个,如果启用则使用第一个,如果禁用则使用第二个。\n以下内容来自 Microsoft 的博客(使用 Active Directory 在 IIS 上激活客户端证书映射所需进行的更改的完整列表) :

\n

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

\n
\n

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

\n

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

\n

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

\n

杂项注释

\n

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

\n

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

\n

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

\n

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

\n

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

\n