证书链检查

信息安全 tls 公钥基础设施 客户端 客户
2021-08-26 18:59:59

我有一个非常具体的问题。

客户端通过获取证书并检查特定值以及中间 CA 的数字签名是否正确(根据存储在客户端计算机上的公钥)来验证服务器。

  • 选项 A: 客户端是否不确保中间 CA 签名(由根 CA 签名)有效,以及根数字签名(由根 CA 自签名)与存储在计算机上的公钥相关联?

或者

  • 选项 B: 客户端是否看到服务器的数字签名是正确的,因此使用存储在证书存储中的信息来组成链的其余部分(即,如果证书 B 用于签署服务器证书,那么我的证书存储说证书 A 用于签署证书 B,因此我将把它作为链的其余部分展示)

我了解整个链都安装在服务器上,但是客户端使用所有证书吗?

这是由我的普遍兴趣引发的,我遇到了一个没有正确安装中间证书的案例,Google Chrome 和 Internet Explorer 接受了它,但 Firefox 4.0 没有。

我希望我的问题尽可能清楚。

为了不混淆问题,我特意去掉了 SSL 验证中使用的其他一些步骤。

注意:我在编辑时发现了与此问题相关的不可见图像:

在此处输入图像描述

3个回答

服务器将提供自己的证书,并可选择(但推荐)链中的所有中间CA 证书(又名CA 捆绑包)。它不需要提供链的根 CA 证书,如果捆绑包中提供了该证书,客户端应该忽略该证书,有关更多详细信息,请参阅此问题由于完整的包很可能是不需要的开销,将来客户端将能够声明它具有它的缓存副本以减少连接设置。

验证的要点是客户端应该能够验证整个链到一个受信任的根,因此它必须已经拥有根的副本,并且必须拥有或获得所有中间体。

如果客户端缺少中间 CA 证书,只要它们是可验证的,它就可以信任服务器提供的证书,然后它可以使用其本地 CA 证书副本填充任何缺失的部分。这是用于中间 CA 证书更新的方法,以便客户端可以轻松更新(没有类似于 PGP 密钥服务器的广泛部署的 X.509 证书获取或发布系统)。一个链中可以有零个、一个或多个中间证书。

每个证书只有其直接颁发者/父级(即不是整个链)的识别详细信息——这记录在颁发者DN 字段中,更有用的是在 AKID 字段(AKID/SKID PDF)中。可读的颁发者名称可能无法唯一标识特定证书(它不记录特定序列号)。SKID(主题密钥标识符)实际上是证书的指纹,AKID (授权密钥标识符)是其颁发者的指纹,这就像从最终证书(理想情况下)到受信任根的单链表(尽管较旧的证书通常缺少这些字段,因此使用了 DN)。

  • 从服务器提供的链(如果存在)开始,客户端应该处理列表,如果它们是有效的,它可以将缺少的中间证书添加到其存储中。
  • 然后,客户端应该从服务器证书进行追溯,通常使用 AKID 字段来定位特定的颁发者(父)证书,验证并继续工作,直到它到达受信任的自签名根。

与此过程相关的术语是认证路径构建认证路径验证没有单一的“正确方法”可以做到这一点。健壮的客户端将端到端检查,浏览器通常会提供绕过(​​带有严厉的警告),并且在某些系统上,您可以限制从最终证书到检查的深度作为优化。

(有效性检查包括签名/哈希、日期范围、CRL、OCSP、固定等,可能还有DANE。)

这与您的两个选项以及中间 CA 证书的自我更新重叠。

通过从服务器证书开始并验证签名直到找到受信任的根来验证信任链。因此,站点证书的签名将根据中间 CA 的公共证书进行验证。然而,中间 CA 不受信任,因此中间 CA 的公共证书的签名将根据根 CA 的公共证书进行验证。由于签名是有效的(并且没有撤销列表条目表明它不再有效),中间 CA(以及服务器的证书)从受信任的根证书继承信任。

该过程可以继续进行尽可能多的层次结构,直到获得受信任的证书。例如,如果服务器的证书已手动添加到本地计算机上的受信任证书存储库中,则中间 CA 的签名将永远不会被验证,因为没有必要获得信任。

通常,Server 默认不会发送所有证书链。这取决于服务器的配置方式以及它的所有证书链是否都包含在 Web 服务器的密钥库中。

为了在 Openssl Server 客户端设置上实现这一点,必须将其所有中间体与其自己的证书连接起来。证书应该按照开始时自己的证书和下一个签署此证书的中间证书的顺序,依此类推(可以忽略连接的根 CA,因为它存在于客户端上)。并在服务器端使用与 SSL_CTX_use_certificate_chain_file 相同的证书链列表。现在在客户端上,只需一个根 CA 证书来验证此证书链就足够了。

还有另一种方法与此相反。服务器只是在 SSL 握手中发送自己的证书(由中间证书和根 CA 签名)。在这里,客户端需要同时拥有中间和根 CA 证书来验证整个链。客户端以根 CA 开头的顺序连接中间和根 CA,然后是中间证书,依此类推。(可以忽略此列表中的连接服务器证书)。客户端可以使用 SSL_CTX_use_certificate_file API 并包含这个连接的文件来验证服务器证书。