エラーメッセージ
javax.net.ssl.SSLHandshakeException: (protocol_version) Received fatal alert: protocol_version
別の表記
- javax.net.ssl.SSLHandshakeException: Received fatal alert: protocol_version
JDK 21 以降では、メッセージに括弧付きでアラート名が含まれます。サーバーが拒否する代わりに JVM が受け入れないバージョンを選択した場合、Java は「The server selected protocol version TLS10 is not accepted by client preferences [TLS13, TLS12]」と報告します。
Java (JSSE) — TLS alert 70 received from the server
このエラーの意味
サーバーは JVM が提示した TLS バージョンを拒否し、アラート 70(protocol_version)で応答しました。現在の JDK が提示するのは TLS 1.3 と 1.2 だけです(1.0 と 1.1 は jdk.tls.disabledAlgorithms に含まれています)。そのため、古いバージョンに限定されたサーバーとは、共通のバージョンがありません。
発生する理由
サーバーが TLS 1.0 または 1.1 にしか対応していない
よくあるTLS 1.2 に一度も対応しなかったレガシーなアプライアンス、古い IIS や Java のサーバー、組み込み機器が該当します。
クライアントが、サーバーで無効化されたバージョンに固定されている
ときどきとうになくなったレガシーシステムのために、古い起動スクリプトが https.protocols や jdk.tls.client.protocols を TLSv1 に設定しています。最新のサーバーはこれを拒否します。
修正方法
- 1.
サーバーが受け入れるバージョンを調べる
openssl s_client で各バージョンを試し、古くなっている側を修正してください。
bash for v in tls1 tls1_1 tls1_2 tls1_3; do printf '%-7s ' "$v" echo | openssl s_client -connect legacy.example.com:443 -servername legacy.example.com -"$v" \ -cipher 'DEFAULT:@SECLEVEL=0' >/dev/null 2>&1 && echo accepted || echo refused done - 2.
クライアントのプロトコル固定を解除する
起動スクリプトと JVM オプションで https.protocols や jdk.tls.client.protocols を探し、TLSv1.3 と TLSv1.2 を許可してください。
bash # Do not pin old versions on the client; let JSSE offer 1.3 and 1.2 grep -rn 'https.protocols\|jdk.tls.client.protocols' /etc/default/app* "$JAVA_HOME/conf" 2>/dev/null java -Djdk.tls.client.protocols=TLSv1.3,TLSv1.2 -jar app.jar - 3.
サーバーで TLS 1.2 と 1.3 を有効にする
恒久的な解決策です。サポートが継続しているクライアントはすべて、これらに対応しています。
text # Server side: enable TLS 1.2 and 1.3 ssl_protocols TLSv1.2 TLSv1.3;