客户端是否必须在 ServerHello 之后将 CA 链与客户端证书一起发送?

信息安全 tls 验证 证书
2021-08-24 16:16:59

在 MTLS 握手期间,在 ServerHello 完成后,客户端将客户端证书发送回服务器,我需要知道客户端应该只发送客户端证书还是需要将客户端证书与整个 CA 链一起发送?

我有一种情况,我在 CertificateVerify 后看到握手失败。客户端证书看起来不错,并且它已从服务器也信任的 RootCA 中注销的 subCA 注销(服务器仅信任根 CA,而不是 subCA)。在这种情况下,我们看到客户端只发回没有链的客户端证书。这就是我看到握手失败的原因吗?

我想知道客户端是否将整个 CA 链发回,服务器必须知道客户端由 SubCA 签名,然后由它信任的根 CA 签名。我用谷歌搜索并发现了很多关于服务器向客户端发送带有 CA 链的证书和可接受的 CA 的信息,但没有关于客户端应该做什么的任何信息。

3个回答

您负责为服务器发送足够的链以将您的证书连接到受信任的根。

对于 TLS 1.2,这在RFC 5246中进行了讨论。客户端证书在§7.4.6中定义,其中(除其他外)规定:

客户端证书使用第 7.4.2 节中定义的证书结构发送。

如果您查看第 7.4.2 节,它将证书结构描述为包括certificate_list(强调我的):

这是证书的序列(链)发件人的证书必须在列表中排在第一位。 后面的每个证书必须直接证明它前面的证书。 因为证书验证要求根密钥是独立分发的,所以可以从链中省略指定根证书颁发机构的自签名证书,假设远程端必须已经拥有它才能在任何情况下验证它。

简而言之,服务器应具有受信任的根,但不需要或预期具有可能需要的任何中间证书。如果客户希望验证顺利可靠地进行,则需要提供它们。(服务器发送给客户端的证书也是如此)。

验证客户端证书的服务器与验证服务器证书的客户端完全相同,只是服务器通常只信任一个根 CA,并且服务器通常不愿意下载缺少的中间证书(浏览器会这样做)。

验证客户端证书的服务器需要能够构建从服务器信任的证书(可能是您的根 CA)到最终实体证书的链。如果这需要中间体,则需要提供中间体,或者除了真实根之外,还需要将中间体配置为服务器上的受信任根。

gowenfawr 的回答确实有帮助,但它也取决于服务器配置。对于nginx,您将需要:

  • ssl_verify_client on;
  • ssl_verify_depth 2; (或者更多)

文档中的更多信息