Chr*_*s J 5 windows iis ssl client-certificate
我们有一个 2008R2 IIS 服务器,其中的站点配置为需要客户端证书。我们的测试客户端无法工作,我们正在尝试调试原因。
在此过程中,我们设置了一个新的 Server 2008 R2 机器(是的,我知道它很旧,但这就是运行该软件的机器)来尝试复制或确定故障排除方法。
我们正在研究的一种途径是 TLS 握手。测试应用程序是用 .NET 编写的,并System.Diagnostics启用了适当的调试,这会将以下条目放入日志文件中:
System.Net 信息:0:[22724] SecureChannel#48979325 - 我们有用户提供的证书。服务器已指定 10 个颁发者。寻找与任何颁发者匹配的证书。
我们无法看到此发行者列表,因此我们爆发了 OpenSSL。运行以下命令:
openssl s_client -connect win2k8r2-1.hsl10690.test:443 -state -no_ticket -servername win2k8r2-1.hsl10690.test
Run Code Online (Sandbox Code Playgroud)
结果输出如下:
[...]
-----END CERTIFICATE-----
subject=/CN=testcert.hsl10690.test
issuer=/CN=Internal Dev CA 1
---
No client certificate CA names sent
---
SSL handshake has read 1013 bytes and written 329 bytes
[...]
Run Code Online (Sandbox Code Playgroud)
因此,我们有一个不匹配的情况,Microsoft 堆栈声明服务器指定了 10 个颁发者,但 OpenSSL 报告服务器没有发送 CA 名称。
对于实时系统,System.Diagnostics 日志报告服务器指定的 130 多个颁发者,但 OpenSSL 仍然返回零。
我们认为问题在于我们提供的客户端证书与颁发者之一不匹配(但我们已经验证了根证书位于服务器的信任存储中,并且我们已经在服务器外部验证了证书)。在实时服务器上,我们在日志中看到“服务器已指定... ”消息之后:
System.Net Information: 0 : [36484] SecureChannel#33675143 - We have user-provided certificates. The server has specified 133 issuer(s). Looking for certificates that match any of the issuers.
ProcessId=20372
DateTime=2018-12-20T13:33:39.9042036Z
System.Net Information: 0 : [36484] SecureChannel#33675143 - Left with 0 client certificates to choose from.
ProcessId=20372
DateTime=2018-12-20T13:33:39.9052036Z
Run Code Online (Sandbox Code Playgroud)
在测试时,一切正常,它说:
System.Net Information: 0 : [22724] SecureChannel#48979325 - We have user-provided certificates. The server has specified 10 issuer(s). Looking for certificates that match any of the issuers.
ProcessId=22100
DateTime=2018-12-21T13:52:23.3718249Z
System.Net Information: 0 : [22724] SecureChannel#48979325 - Selected certificate: [Version]
V3
[Subject]
Run Code Online (Sandbox Code Playgroud)
我们如何找出服务器返回了哪些证书,如果我们发现列表中缺少颁发者,那么是什么阻止了根被包含在内?我不排除我们错过了一些明显的东西,但我们还没有看到它。
我们终于找到了答案:故障是KB931125。一篇博客文章将该知识库描述为仅适用于客户端目标,但被发送到服务器,导致 IIS 发送的 CA 列表被截断。它并没有真正解释为什么我们看不到使用 OpenSSL 传输的 CA 列表,但最终它确实让我们找到了根本原因。
该博客文章指向另一篇 MSDN 文章,该文章更详细地描述了该问题:
如果 TLS/SSL 服务器的受信任根证书列表中包含许多条目,则可能会出现这些问题。如果满足以下条件,服务器会向客户端发送受信任的证书颁发机构列表:
- 服务器使用传输层安全性 (TLS)/SSL 协议来加密网络流量。
- 认证握手过程中需要客户端证书进行认证。
此受信任的证书颁发机构列表代表服务器可以接受客户端证书的颁发机构。要通过服务器进行身份验证,客户端必须具有存在于服务器列表中的根证书的证书链中的证书。这是因为客户端证书始终是链末端的最终实体证书。客户端证书不是链的一部分。
目前,在 Windows Server 2008、Windows Server 2008 R2 和 Windows Server 2012 中,Schannel 安全包支持的受信任证书颁发机构列表的最大大小为 16 KB。
还记录了一个事件日志条目,其中显示(我们第一次查看此内容时错过了):
当请求客户端身份验证时,该服务器会向客户端发送受信任的证书颁发机构列表。客户端使用此列表来选择服务器信任的客户端证书。目前,该服务器信任如此多的证书颁发机构,以致该列表变得太长。该列表因此被截断。该计算机的管理员应该检查客户端身份验证所信任的证书颁发机构,并删除那些实际上不需要信任的证书颁发机构。
MSDN 文章确实列出了修复:
删除以下注册表项:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\AuthRoot\Certificates
为此,请按照下列步骤操作:
- 启动注册表编辑器
- 找到以下注册表子项:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\AuthRoot
- 右键单击,然后删除名为“证书”的项
| 归档时间: |
|
| 查看次数: |
2654 次 |
| 最近记录: |