SSL根证书可选?

信息安全 tls 证书 公钥基础设施 证书颁发机构
2021-08-11 22:41:08

我可能对如何设置服务器以及在服务器 hello 证书消息期间实际发送的证书有错误的印象。我今天从 Symantec/VeriSign 遇到了这个问题:

根安装在服务器上。为获得最佳实践,请从服务器中删除自签名根。证书包应该只包含证书的公钥,以及任何中间证书颁发机构的公钥。浏览器将仅信任解析为已在其信任存储中的根的证书,它们将忽略证书包中发送的根证书(否则,任何人都可以发送任何根)。

如果这是真的,并且不需要在服务器上安装根证书,那么我认为我知道正确的服务器设置以及如何将链验证回根。再一次,当我回顾这个问题时,在Thomas Pornin 的答案的证书和身份验证部分下,它说:

因此,客户端应该执行以下操作:

  • 获取以服务器证书结尾的证书链。来自服务器的证书消息应该准确地包含这样一个链。

这与上面的 Symantec/VeriSign 消息几乎相反,除非我误解了某些东西。所以:

  1. 服务器是否需要安装完整的链,包括根?如果不是,浏览器使用什么来比较验证,因为服务器在握手期间不会提供其根证书?它只是查看身份证书并从那里获取吗?(比如在您的本地机器上打开一个身份证书,并在证书路径中看到完整的链?)

  2. 同样,如果这是真的,那么使用 SSL 库的独立客户端应用程序呢?这是否取决于应用程序,因为它可能对受信任的根和浏览器有不同的路径构建方法?

4个回答

服务器总是发送一个链。根据TLS 标准,链可能包含也可能不包含根证书本身;客户端不需要该根,因为它已经拥有它。而且,确实,如果客户端还没有根,那么从服务器接收它也无济于事,因为只有根已经存在才能信任根。

赛门铁克说的是他们建议不要发送根,只发送链的其余部分。这是有道理的:因为根对于验证目的是无用的,您最好避免发送它并为每个连接节省 1 kB 左右的数据带宽。

反正:

  • 服务器的证书及其链不适用于服务器。服务器对自己的证书没有用处。证书总是给其他人(这里是客户)。服务器使用的是它的私钥(对应于证书中的公钥)。特别是,服务器不需要信任它自己的证书或任何颁发它的 CA。

  • 在 TLS 中,服务器应该发送一个链;并且客户端应该以某种方式使用服务器的公钥进行握手。客户端可以以任何它希望的方式自由地“知道”该公钥,尽管当然期望客户端将从服务器刚刚发送的证书链中获取服务器的公钥。浏览器将主要尝试使用服务器发送的链(通过尝试将其链接到浏览器已经信任的根之一之下);如果失败,他们将尝试基于他们已经知道或可以即时下载的中间 CA 证书构建其他链。

    在独立应用程序中,应用程序编写者可以以任意方式自由配置或绕过该步骤,如果服务器的公钥可以在应用程序代码中硬编码(在这种情况下服务器发送的链被完全忽略),这将很有用)。不幸的是,实施自定义证书验证步骤的自由也是打击安全、将其刺死然后将其尸体扔进沟里的自由。它发生得太频繁了。

由于服务器在握手期间不会提供其根证书,浏览器使用什么来比较验证

证书检查的整个想法是,客户端有一些它信任的根证书(随浏览器或操作系统一起提供),并且它验证浏览器针对这个本地信任锚发送的证书。

这意味着,服务器不需要(也不应该)将根证书发送给客户端,因为该根证书应该已经在客户端。如果它仍然发送根证书,客户端将简单地丢弃它,即它不会信任服务器发送的任何根证书。

同样,如果这是真的,那么使用 SSL 库的独立客户端应用程序呢?这是否取决于应用程序,因为它可能对受信任的根和浏览器有不同的路径构建方法?

浏览器和 SSL 库之间的基本验证过程是相同的。在 openssl 和浏览器之间的边缘情况下,路径构建存在一些差异(请参阅http://rt.openssl.org/Ticket/Display.html?id=2732&user=guest&pass=guest)以及目标主机名的验证服务器证书中的名称通常有问题,甚至在常见浏览器之外不存在。

我会在方便的时候发送根目录。

如果客户端信任根,那么无论您是否发送它都没有区别。

当客户端无法识别根时,根据我的经验,如果在链中提供了不受信任的根,则 MS Windows 客户端会产生更少令人困惑的诊断消息。

至于如果没有提供它如何知道使用哪个根,next-to-root(必须在提供的链中)包含根的标识信息,客户端使用该信息在客户的商店。

考虑到如果根 CA 未包含在密钥库中,则存在根本不会启动的服务器软件(如 IBM HTTP Server)