跳到主要内容
ecdsa.com
Java (JSSE)Java

错误信息

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 中),因此只支持旧版本的服务器与它们没有共同的版本。

原因

修复方法

  1. 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. 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. 3.

    在服务器上启用 TLS 1.2 和 1.3

    这是长久之计:所有仍在维护的客户端都支持这两个版本。

    text
    # Server side: enable TLS 1.2 and 1.3
    ssl_protocols TLSv1.2 TLSv1.3;

相关错误

浏览完整的签名错误库