[英]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! 但是,由於這是一台生產服務器,需要執行許多操作,所以我不想在第一步中這樣做。 但是它解決了。
關於發生的事情,我最好的猜測是:
真正奇怪的是,即使針對不同的IP(我針對第三方的測試服務器嘗試)和具有不同的密鑰庫(我制作了更新的密鑰庫的副本並發出使用該密鑰庫的請求),它的行為也相同。 最初的錯誤是“ Stream不是有效的PKCS12密鑰庫” ,並且堆棧跟蹤返回到試圖在我們的代碼中打開密鑰庫的行。 修復了密鑰庫格式之后,它在我們的代碼中有了更進一步的處理(堆棧跟蹤現在返回到client.execute()
),但是失敗了,返回了_Unsupported握手消息:server_hello_done_。
我創建了整個tomcat文件夾(包括jre)的副本,最初帶有原始的(無效的)密鑰庫,將其更改為在另一個端口上運行,然后在同一台機器上的該tomcat旁邊啟動了它。 它的行為相同,但是重新啟動后可以工作。 今天早上,我重新啟動了主要服務,現在可以使用了
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.