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,但服务器无视这一点,以 TLS 1.0(TLS10)或 1.1(TLS11)作出回应,而 JVM 不接受这两个版本。Java 在自己这一端中止握手。服务器对当前的客户端来说太旧了;任何已更新到最新的 JDK、浏览器和 curl 都会有同样的反应。
原因
服务器只实现了 TLS 1.0/1.1
常见TLS 协议栈早于 TLS 1.2(或关闭了 TLS 1.2)的旧服务器、硬件设备和嵌入式设备。
终止 TLS 的老旧中间设备
偶见现代服务器前面的负载均衡器或代理,用过时的协议栈终止 TLS。
JDK 已更新
偶见2021年,安全更新在所有仍在维护的 JDK 版本系列中禁用了 TLS 1.0 和 1.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.
确认服务器缺少 TLS 1.2
如果 TLS 1.2 握手失败而 TLS 1.0 成功,就必须升级服务器。
bash echo | openssl s_client -connect legacy.example.com:443 -servername legacy.example.com -tls1_2 -brief - 3.
最后手段:在单个隔离的 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
相关错误
javax.net.ssl.SSLHandshakeException: (protocol_version) Received fatal alert: p…Java (JSSE)No appropriate protocol (protocol is disabled or cipher suites are inappropriat…Java (JSSE)curl: (35) TLS connect error: error:0A000102:SSL routines::unsupported protocolcurl (OpenSSL backend)tls: server selected unsupported protocol version 301Go crypto/tls client