本文へスキップ
ecdsa.com
Java (JSSE)Java

エラーメッセージ

The server selected protocol version TLS10 is not accepted by client preferences [TLS13, TLS12]

別の表記

  • javax.net.ssl.SSLHandshakeException: (protocol_version) The server selected protocol version TLS10 is not accepted by client preferences [TLS13, TLS12]

選択されたバージョン(TLS10、TLS11)と角括弧内のリストは、サーバーと、JVM で有効なプロトコルによって異なります。JDK 21 以降では、例外のテキストの先頭に「(protocol_version) 」が付きます。ダウングレードせずに拒否するサーバーでは、「Received fatal alert: protocol_version」になります。

Java (JSSE) — the server picked a TLS version the JVM does not allow

このエラーの意味

JVM は TLS 1.3 と 1.2 を提示しましたが、サーバーはそれを無視して、JVM が受け入れない TLS 1.0(TLS10)または 1.1(TLS11)で応答しました。Java は自分の側でハンドシェイクを中止します。このサーバーは現行のクライアントには古すぎます。最新の JDK、ブラウザー、curl はいずれも同じように反応します。

発生する理由

修正方法

  1. 1.

    サーバーで TLS 1.2 以降を有効にする

    すべてのクライアントに効果がある解決策です。TLS 1.0 と 1.1 は正式に非推奨となっています(RFC 8996)。

    text
    # Enable TLS 1.2 (and 1.3) on the server or appliance
    ssl_protocols TLSv1.2 TLSv1.3;                 # nginx
    SSLProtocol -all +TLSv1.2 +TLSv1.3             # Apache httpd
  2. 2.

    TLS 1.2 に対応していないことを確認する

    TLS 1.0 のハンドシェイクは成功するのに TLS 1.2 のハンドシェイクが失敗する場合は、サーバーをアップグレードする必要があります。

    bash
    echo | openssl s_client -connect legacy.example.com:443 -servername legacy.example.com -tls1_2 -brief
  3. 3.

    最終手段:隔離した 1 つの JVM でだけ TLS 1.0/1.1 を許可する

    JDK 自身の値をもとに作成したセキュリティプロパティの上書きを使うと、その JVM に限って古いバージョンが再び有効になります。TLS 1.0/1.1 は、既知の弱点がある SHA-1 や CBC を使った構成に依存しているため、この設定は信頼できるネットワークに限定し、機器を交換したら削除してください。

    bash
    # Last resort for ONE JVM that must reach the legacy server: drop TLSv1/TLSv1.1 from
    # this JDK's own jdk.tls.disabledAlgorithms value and pass it as an override
    v=$(sed -n '/^jdk.tls.disabledAlgorithms=/,/[^\\]$/p' "$JAVA_HOME/conf/security/java.security" | sed 's/\\$//' | tr -d '\n')
    printf '%s\n' "$v" | sed -E 's/ TLSv1(\.1)?,//g' > legacy-tls.security
    java -Djava.security.properties=legacy-tls.security -jar legacy-client.jar

関連するエラー

署名エラーデータベースをすべて見る