![FF 中的“选择客户端证书”对话框仅显示可用客户端证书的子集](https://linux22.com/image/753885/FF%20%E4%B8%AD%E7%9A%84%E2%80%9C%E9%80%89%E6%8B%A9%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%AF%81%E4%B9%A6%E2%80%9D%E5%AF%B9%E8%AF%9D%E6%A1%86%E4%BB%85%E6%98%BE%E7%A4%BA%E5%8F%AF%E7%94%A8%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%AF%81%E4%B9%A6%E7%9A%84%E5%AD%90%E9%9B%86.png)
问题:
我们这里有一个使用客户端证书身份验证的应用程序。多年来,它一直运行良好,没有任何问题,但现在几个客户端在 FF 和 Chrome 中遇到了以下问题,但在 IE 中还没有:不再出现“选择客户端证书”对话框,因此它们被重定向到用户名/密码登录页面。因此,我认为浏览器无法识别已安装的客户端证书是否适合服务器发送的 CA 名称。
我已经检查过:
- 所有证书(服务器或客户端)均未过期。
- nginx 正在向客户端发送正确的 CA 名称。我使用 openssl s_client 检查了...
- 我已经阅读了 FF 更新日志,以查找任何与客户端证书相关的内容,但到目前为止还没有任何内容可以解释这个问题
我已尝试过:
- 我从 nginx 配置中删除了“ssl_client_certificate”和“ssl_verify_depth”,浏览器中的选择客户端对话框又出现了,只是这次显示了所有已安装的证书,包括我们应用程序的证书。选择正确的证书后,登录成功,应用程序运行正常。
这让我得出结论,发送给客户端的 CA 名称可能有问题,而证书本身没有问题。 - 正如我之前提到的,并非所有客户端都遇到此问题,因此我在测试机器上安装了来自工作客户端的客户端证书和来自非工作客户端的客户端证书。我应该注意,这两个证书都是由同一个 CA 颁发的(工作证书只比工作证书早几个月)。猜猜怎么着:当我尝试访问应用程序时,会出现“选择证书”对话框,但它只显示一个证书(来自工作客户端的证书)。如果我再次从 nginx 配置中删除“ssl_client_certificate”指令,我可以选择(并成功登录)两个证书中的任何一个。与 (1.) 相比,这似乎其中一个证书存在问题
现在我所能做的就是引用萨姆纳·米勒先生的话:“为什么会这样?”
我希望有人以前遇到过类似的问题,因为我唯一的其他选择就是深入研究 FF 的源代码,看看如何构建合适的客户端证书列表。该客户端证书对话框的行为肯定最近发生了变化,所以我接下来要做的就是在我的测试机器上降级 FF,直到它再次正常工作。
环境:
服务器:centOS 7、nginx 1.19.0、openssl 1.1.1f
客户端:Ubuntu 19.10 上的 Firefox 77、Chrome 83 以及多个版本的 Windows
nginx配置:
ssl_verify_client optional_no_ca;
ssl_client_certificate /etc/ssl/certs/waf_client_ca.pem;
ssl_verify_depth 2;
笔记:
- 之所以有“optional_no_ca”,是因为出于“历史原因”,客户端证书的验证是在 nginx 之外处理的。如果我将其设置为“yes”或“optional”,浏览器行为不会改变。
- 如果我不得不替换所有这些证书,那将非常糟糕,所以是的:我已经考虑过设置一个全新的 CA 并为所有客户端颁发新证书,但有成千上万个证书,所以我真的尽量避免这种情况。至少在我确切知道至少一些现有证书的问题之前。
答案1
好的,在深入研究 FF 源并进行更多信息安全搜索后,我找到了解决方案:
在https://security.stackexchange.com/questions/68491/recommended-key-usage-for-a-client-certificatephilippe lhardy 描述了 libnss 执行的证书检查以及必须满足的标准:
- EKU 和 KU 未设置。
- KU 未设置并且 EKU 设置为 clientAuth 并且证书不是 CA。
- KU 包含 digitalSignature 且 EKU 未设置
- KU 包含 digitalSignature 并且 EKU 设置为 clientAuth 并且 cert 不是 CA。
这篇文章是 2015 年的,现在似乎不太正确了,因为必须将 EKU 设置为 clientAuth,否则证书不会显示在对话框中。仅设置 KU 字段已经不够了。不过这有点奇怪,因为如果服务器不传输任何 CA 名称,似乎就不会执行此检查……也许有人知道并可以解释为什么会这样。