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

Java 尽管Netty 4.1.36和jdk 11中的证书不正确,但握手成功,java,ssl,netty,tls1.2,java-11,Java,Ssl,Netty,Tls1.2,Java 11,我已将客户端和服务器配置为使用TLS和自签名证书 客户端SSL引擎配置为使用虚拟信任管理器,该管理器从不抛出CertificateException和空KeyManager数组 服务器SSL引擎使用由手动生成的密钥存储文件初始化的密钥存储 当我使用JDK 8运行它时,会得到以下握手结果: 服务器无法验证证书 在客户端线程中,我可以看到调用了io.netty.handler.ssl.SslHandler#setHandshakeFailure 而io.netty.handler.ssl.SslH

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

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

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

当我使用JDK 8运行它时,会得到以下握手结果:

  • 服务器无法验证证书
  • 在客户端线程中,我可以看到调用了
    io.netty.handler.ssl.SslHandler#setHandshakeFailure
    io.netty.handler.ssl.SslHandler#setHandshakeSuccess
    永远不会成功 打电话来
这是预期的行为

当我使用JDK 11运行它时,我得到以下结果:

  • 服务器失败并出现相同错误(空证书链),但在客户端线程中我看到以下情况:
  • 首先调用io.netty.handler.ssl.SslHandler#setHandshakeSuccess
  • io.netty.handler.ssl.SslHandler#setHandshakeFailure
我是TLS1.3新手,可能在配置中遗漏了一些东西。同时,文档指出,java TLS API客户机切换到TLS 1.3无需更新

这种行为令人困惑,它进一步破坏了基于
握手协议的逻辑

再现该问题的完整代码可通过gist链接获得:


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

需要说明的是,您的服务器请求客户端身份验证,而客户端证书的服务器验证失败,因为客户端没有配置keymanager,因此没有发送证书?(然而,服务器发送了自己的“手动”证书,但由于虚拟trustmanager,客户端接受了该证书。)

如果是这样的话,这看起来像是jetty遇到的类似问题(?)参见中的第五篇文章-,在我看来,这是因为TLS 1.3客户端认为在发送时握手完成(因为1.3将服务器移动到第一个航班),这是在接收到客户端身份验证失败的服务器警报之前。(而在1.2及更早版本中,服务器完成了,可能是票证基本上是第二次飞行,导致客户端第一个应用程序协议(如HTTP)的额外RTT。)

如果使用,它也是在接收服务器NewSessionTicket(针对1.3“恢复”进行了修改)之前;看


我想对于1.3,您必须在“成功”之后接受“失败”,除非Java人员能够想出一些非常聪明的解决方法。

是的,这是正确的。谢谢,那么我将尝试在代码中的“成功”之后处理“失败”。