尽管 Netty 4.1.36 和 jdk 11 中的证书不正确,但握手成功

Successful handshake despite bad certificate in Netty 4.1.36 and jdk 11

我将客户端和服务器配置为使用 TLS 和自签名证书。

客户端 SSL 引擎配置为使用虚拟信任管理器,它永远不会抛出 CertificateException 和空 KeyManager 数组。

服务器 SSL 引擎使用使用手动生成的密钥库文件初始化的密钥库。

当我 运行 它与 JDK 8 我得到以下握手结果:

这是预期的行为。

当我 运行 它与 JDK 11 我得到以下内容:

我是 TLS 1.3 的新手,可能在配置中遗漏了一些东西。同时,文档说 java TLS API 客户端无需更新即可切换到 TLS 1.3。

这种行为令人困惑,它打破了基于 handshakePromise 的进一步逻辑。

gist link 提供了重现该问题的完整代码: https://gist.github.com/kiturutin/ccb710f67ccfb0a7a7de1fb3b3099b60

这是一个 groovy 脚本,它首先启动服务器,然后启动客户端。

需要说明的是,您的服务器请求客户端身份验证和服务器验证 客户端证书 失败,因为客户端没有配置密钥管理器,因此没有发送证书? (而服务器发送自己的 'manual' 证书没问题,客户端因为虚拟信任管理器而接受了它。)

如果是这样的话,这看起来像码头有一个类似的问题(?)——参见 https://github.com/eclipse/jetty.project/issues/2711 中的第五个 post——在我看来,这是因为 TLS 1.3 客户端考虑了握手在发送 Finished 时完成(因为 1.3 将服务器 Finished 移动到第一次飞行)并且那是在收到客户端身份验证失败的服务器警报之前。 (而在 1.2 和更早版本中,服务器完成并且可能的票证基本上 第二次飞行,导致客户端优先应用程序协议(如 HTTP)的额外 RTT。)

如果使用,也是在接收服务器 NewSessionTicket 之前(为 1.3 'resumption' 修改);见 OpenJDK 11 problem - Client finished handshake before last UNWRAP .

我想对于 1.3,你必须在 'success' 之后接受 'failure',除非 Java 的人可以想出一些非常聪明的解决方案。