Java 11 怎么可能验证中间证书在 cacerts 中不可用的证书?

How is is possible that Java 11 validates a certificate whom intermediate certificate isn't avalaible in cacerts?

我不必修复不起作用的东西,但我会尝试理解为什么会起作用,因为我认为它不应该起作用。

我正在使用 OpenJDK11 / Ubuntu 16.04。我进行 HTTPS 调用。 SSL 握手成功。

证书链包含 3 个证书:

第二个证书在正在使用的 cacert 密钥库中不可用(lib/security 文件夹下的默认密钥库)。这听起来很正常,因为证书是在 2021 年 4 月颁发的,而 JRE 是在 2021 年 1 月发布的(openjdk 版本“11.0.10”2021-01-19)

为什么这次握手能够成功?在我看来,由于 Java 不知道第二个证书,因此无法验证 API 证书。

为了在 ssl 握手阶段验证服务器证书,http 客户端需要用于签署服务器证书的证书(中间证书),以及用于签署中间证书的证书(根证书)。

所有这些证书构成了所谓的“证书链”。通常只有一个中间证书,有时没有中间证书(由根证书直接签名的服务器证书),或者您可以有多个中间证书。

JCE/JSE 需要所有这些证书来验证服务器身份。如果一个证书丢失(通常是根证书)、被篡改或无效,或者在某些情况下由于网络故障或错误的服务器设置,java 抛出 SSLHandshakeException。

Java 在他的可信存储中查找根证书(根据 JRE 设置:有默认值,它们可以通过不同的方式覆盖) 服务器证书由服务器发送。

我认为中间证书也必须存在于 java 受信任的存储区中。这是一个错误。其实中间证书也是服务端发的

我没有 SSLHandhakeException 而中间证书不存在于 java 信任库中,所以我不明白。说到这里,又写了几行java看服务器发的是什么,现在明白了中间证书是服务器发的

因此,您无需在 java 信任库中拥有中间证书即可使 ssl 握手成功。