1. ホーム
  2. Java

javax.net.ssl.SSLHandshakeException: リモートホストがハンドシェイク中に接続を閉じた 解決までの道のりは険しい

2022-02-22 10:11:03

先週、別のプロジェクトチームの同僚がやってきて、2日間解決しない問題に遭遇したと言い、そのエラーは次のようなものだったという。

javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:980) ~[na:1.8.0_45]
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1363) ~[na:1.8.0_45]
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1391) ~[na:1.8.0_45]
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1375) ~[na:1.8.0_45]
        at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563) ~[na:1.8.0_45]
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) ~[na:1.8.0_45]
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153) ~[na:1.8.0_45]
        at com.dangdang.ddframe.job.executor.type.SimpleJobExecutor.process(SimpleJobExecutor.java:41) [elastic-job-common-core-2.1.5.jar:na ]
        at com.dangdang.ddframe.job.executor.AbstractElasticJobExecutor.process(AbstractElasticJobExecutor.java:206) [elastic-job-common-core-2.1.5.jar:na ] core-2.1.5.jar:na]
        at com.dangdang.ddframe.job.executor.AbstractElasticJobExecutor.process(AbstractElasticJobExecutor.java:171) [elastic-job-common- core-2.1.5.jar:na]
        at com.dangdang.ddframe.job.executor.AbstractElasticJobExecutor.execute(AbstractElasticJobExecutor.java:150) [elastic-job-common- core-2.1.5.jar:na]
        at com.dangdang.ddframe.job.executor.AbstractElasticJobExecutor.execute(AbstractElasticJobExecutor.java:122) [elastic-job-common- core-2.1.5.jar:na]
        at com.dangdang.ddframe.job.lite-internal.schedule.LiteJob.execute(LiteJob.java:26) [elastic-job-lite-core-2.1.5.jar:na]
        at org.quartz.core.JobRunShell.run(JobRunShell.java:202) [quartz-2.2.1.jar:na]
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [quartz-2.2.1.jar:na]
Caused by: java.io.EOFException: SSL peer shut down incorrectly
        at sun.security.ssl.InputRecord.read(InputRecord.java:505) ~[na:1.8.0_45]
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:961) ~[na:1.8.0_45]
        ... 21 common frames omitted

同僚によると、これは3者間 https インターフェースを呼び出すために使用する httpclient で、ローカルのユニットテストには問題なく、ブラウジングで開くには問題ないそうです。

以前にも同じような問題に遭遇したため、自信を持ってウェブで解決策を探したところ、例えば多くの選択肢が見つかりました。System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2") のように、多くの選択肢がありました。

そして

SSLContext sslContext = SSLContext.getInstance(
"TLSv1.2"
);
 どちらも動作しません。

また、この問題があるのはjdk1.7だと書いてありますが、うちの環境自体は1.8です。これらの方法で多少なりとも解決している他の方のコメントを見ていると、本当に不安になってきました。

我々はそれを考え、三者間インタフェースが移動しなかった、環境が移動しなかった、私たちのローカル回線、テスト環境が動作しない、と環境の問題だと思い、jdkのバージョンを見て、ローカルは1.8.0_131ですが、テスト環境は1.8.0_45、それは問題ではないだろうと思った、45にダウングレードを行うには、ローカルjpが、悲しいことにテスト環境の問題のローカル再現がない、この時点で、我々は唯一の疑いのネットワークの問題、それをチェックするにはどうすればいい?パケットをつかむ。

パッケージの取得後、ローカルのパッケージとテスト環境のパッケージを比較したところ、いくつかの問題が見つかりました。

クライアントは、3つのTCPハンドシェイク後にクライアントこんにちはを送ったが、サーバーは、ハンドシェイクの失敗を返さなかった 問題はここにあるはず、通常のパケットとこのパケットを比較し、繰り返し比較した後、まだに問題を見ることができないので、ネットワークの同僚を見つけ、ネットワークの同僚も一緒に支援するために表示されます。

最後に、こんな投稿を見つけました。 Java暗号化スイート強度制限によるSSLハンドシェイクの不具合  比較してみましたが、ほぼ同じ状況でした。筆者が問題を発見するために使った方法(検証方法は上記の投稿を参照、重複しないように)をすべて試しましたが、すべて一致しました。

ファイルをダウンロードせずに jdk を 1.8.0_151 以降にアップグレードし、Javajreiblibsecurityjava.security ファイルを修正するだけです。

crypto.policy=unlimited

今回は本当に問題が解決しました!こちらの原作者の方に感謝です。

この方法でも、jdk の設定ファイルを修正しなければなりませんが、オンライン環境が均一であることを考えると、ファイルを修正すると jdk の整合性が取れなくなるので、何か良い方法はないかと探してみたところ、案の定、別の記事を目にすることになりました。 Java SE 8u151、8u152、8u162におけるJCEポリシーの変更点  記事には、"OracleがJava 8 u162をリリースした、とある。このバージョンでは、無制限ポリシーは  デフォルトで有効 . JRE にポリシーファイルをインストールしたり、セキュリティプロパティを設定したりする必要はありません。  crypto.policy ."

jdk 1.8.0_162 以降のバージョンから crypto.policy is set to unlimited by default, so we just upgrade jdk to the final update of 1.8 Java SE 8u181 これで問題解決!

バグの件  JDK-8170157

要約すると

問題の最終的な解決は、以前の記事のほとんどを参照して、ステップバイステップの解決として自分自身を数えることはありません、私がここで話したいことは、問題に対するアプローチとアイデアです。

1.持続しなければならない、多くの問題いくつかの同僚は、終了する方法はありません見つけるためにオンラインに行く

2. 最初に考える、それを自分で解決する、情報を見つけるために、より多くのオンラインに対処することはできませんが、相互接続は、よく借りて、生活のために私たちに同行する教師かもしれない

3. これは、ネットワークの知識や、tcpなどのネットワークの問題に対処する方法を多く使用しています。 エスエスエル / TLS , ハンドシェイク、パケットキャプチャなど、開発者としてこれらは私たちから遠く離れていると感じるかもしれません、我々はそれを使用していない、唯一のJavaの この人生、後輩プログラマーにしかなれないとしか言いようがない!?

お昼休みを利用してまとめてみましょう!お役に立てれば幸いです。