我已将客户端和服务器配置为使用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
这是一个时髦的脚本,它首先启动服务器,然后启动客户端。
答案 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专家可以想到一些非常聪明的解决方案。