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

时间:2019-05-05 09:13:38

标签: java ssl netty tls1.2 java-11

我已将客户端和服务器配置为使用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在之后被调用

我是TLS 1.3的新手,可能会错过一些配置。同时,文档说,没有任何更新可以将Java TLS API客户端切换到TLS 1.3。

此行为令人困惑,并且破坏了基于handshakePromise的进一步逻辑。

完整的代码可以通过gist链接获得此问题: https://gist.github.com/kiturutin/ccb710f67ccfb0a7a7de1fb3b3099b60

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

1 个答案:

答案 0 :(得分:3)

要清楚,您的服务器请求客户端身份验证和客户端证书的服务器验证 失败,因为客户端没有配置密钥管理器,因此不发送证书? (鉴于服务器发送了自己的“手动”证书,而客户端由于虚假的trustmanager而接受了它。)

如果是这样,这似乎是一个类似的码头问题has(?)-请参阅https://github.com/eclipse/jetty.project/issues/2711的第五篇文章-在我看来,这是因为TLS 1.3客户端认为在完成发送时握手已完成(因为1.3将服务器“完成”运行到第一个航班),并且这是在收到有关客户端身份验证失败的服务器警报之前。 (而在1.2及更早版本中,服务器Finished和票证基本上是 的第二次飞行,这会导致客户端优先应用程序协议(例如HTTP)产生额外的RTT。)

如果使用服务器,也要在接收服务器NewSessionTicket(针对1.3“恢复”进行了修改)之前;参见OpenJDK 11 problem - Client finished handshake before last UNWRAP

我猜对于1.3,您必须在“成功”之后接受“失败”,除非Java专家可以想到一些非常聪明的解决方案。