ーはじめにー
JavaでSSL通信を行う実装をしていて、タイトルの通り、「java.net.SocketException: Connection reset」が発生。例外情報が少なすぎて原因が全く分からず、大ハマリしました。。
【環境】
- Java:version 1.8.0.130
- サーバサイドSSL/TLS:TLSv1
【原因】
上記環境に書いてあることがまさにそのまま原因なのですが、要はJavaとサーバサイドのSSL/TLSの使用プロトコルの差異のせいでした。
【対策】
- サーバのSSL/TLSプロトコルを最新バージョン(TLSv1.2)にするのが理想。v1やv1.1には脆弱性が報告されているため。
- Java側でSSL/TLSのバージョンを明記する。Java8では、SSL/TLSのデフォルトバージョンはTLSv1.2となり、サーバが対応していなければTLSv1.1となる仕様のよう 。
ちなみに今回は”2″の対策をしました。”1″を変えてもらいたかったんですけどね、大人の事情があって色々難しい。
“2”の具体的な対応としては、Javaのシステムプロパティに設定するというものです。
補足として、明示的に異なるバージョンを指定すると、以下の通り例外が変わります。この例外メッセージならば原因特定が簡単なんですけどね。
Caused by: javax.net.ssl.SSLHandshakeException: Server chose TLSv1, but that protocol version is not enabled or not supported by the client.
ー終わりにー
この例外、SSLパッケージ内の広い例外のようで、調べても関係ない事象ばかりが出てきて、調査がものすごく大変でした。前述の通り、広い例外なので、同じ例外が発生していたとしても今回の解決策とはならないかもしれませんが、一つの策として書いておきます。
ご参考になれば幸いです。