繁体   English   中英

Java 11给出了不支持的握手消息:HTTPS与客户端证书的连接上的server_hello_done

[英]Java 11 gives Unsupported handshake message: server_hello_done on HTTPS connection with client certificate

我们有一个Java小程序(在tomcat下运行),可以调用第三方。 其中之一使用客户端证书进行身份验证。 这是在Java 8下工作的,但是我们最近将系统升级到了Java 11,现在已经不行了。 错误是

不支持的握手消息:server_hello_done

(这很奇怪,因为我认为server_hello_done是握手的有效部分)

升级后,Java密钥库确实存在问题。 服务失败,因为它不是有效的PCKS12流。 使用keytool列出内容是可行的,但带有警告

警告:

JKS密钥库使用专有格式。 建议使用“ keytool -importkeystore -srckeystore / path / to / keystore -destkeystore / path / to / keystore -deststoretype pkcs12”迁移到行业标准格式PKCS12。

我们使用了建议的命令,现在它打开了密钥库OK,但是出现了握手错误。

追溯到我们的代码的堆栈是:

Unsupported handshake message: server_hello_done
javax.net.ssl.SSLProtocolException: Unsupported handshake message: server_hello_done
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:126)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
    at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:446)
    at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
    at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:178)
    at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
    at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1152)
    at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1063)
    at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:402)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:396)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:355)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:359)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:381)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)

我们正在使用apache http客户端(org.apache.http.impl.client.CloseableHttpClient)。 堆栈跟踪的下一行只是对我们代码中的client.execute()的调用。

它还包括

Caused by: java.lang.UnsupportedOperationException: Not supported yet.
        at java.base/sun.security.ssl.HandshakeHash$CloneableHash.archived(HandshakeHash.java:616)
        at java.base/sun.security.ssl.HandshakeHash$T12HandshakeHash.archived(HandshakeHash.java:546)
        at java.base/sun.security.ssl.HandshakeHash.archived(HandshakeHash.java:188)
        at java.base/sun.security.ssl.CertificateVerify$T12CertificateVerifyMessage.<init>(CertificateVerify.java:581)
        at java.base/sun.security.ssl.CertificateVerify$T12CertificateVerifyProducer.produce(CertificateVerify.java:740)
        at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)
        at java.base/sun.security.ssl.ServerHelloDone$ServerHelloDoneConsumer.consume(ServerHelloDone.java:173)
        at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
        at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)

第三方确认他们在日志中看到“没有共享密码”,但表示他们支持各种密码( “ SSL3,TLS 1.0、1.1或1.2。密码被标记为HIGH:MEDIUM:!aNULL:!eNULL: @STRENGTH” )。 我认为我们支持除SSL3之外的大多数内容。 据我所知,我们在Java 11中有默认设置。 尝试暂时激活SSLv3,但无法连接(尽管尝试恢复后即使连我都无法从该计算机连接(超时),所以这可能不多说-我从一台测试计算机而不是生产计算机尝试过)那)。

有任何想法吗? 我是在正确的路线上继续查看密码还是我缺少什么?

原来,所需要做的只是重启tomcat! 但是,由于这是一台生产服务器,需要执行许多操作,所以我不想在第一步中这样做。 但是它解决了。

关于发生的事情,我最好的猜测是:

  • 对于更新的Java版本,密钥库的格式错误
  • 尝试使用无效的密钥库使tomcat / java处于某种奇怪的状态
  • 更新密钥库允许Java使用它,但是它仍然处于某种奇怪的状态
  • 重新启动修复它。

真正奇怪的是,即使针对不同的IP(我针对第三方的测试服务器尝试)和具有不同的密钥库(我制作了更新的密钥库的副本并发出使用该密钥库的请求),它的行为也相同。 最初的错误是“ Stream不是有效的PKCS12密钥库” ,并且堆栈跟踪返回到试图在我们的代码中打开密钥库的行。 修复了密钥库格式之后,它在我们的代码中有了更进一步的处理(堆栈跟踪现在返回到client.execute() ),但是失败了,返回了_Unsupported握手消息:server_hello_done_。

我创建了整个tomcat文件夹(包括jre)的副本,最初带有原始的(无效的)密钥库,将其更改为在另一个端口上运行,然后在同一台机器上的该tomcat旁边启动了它。 它的行为相同,但是重新启动后可以工作。 今天早上,我重新启动了主要服务,现在可以使用了

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM