Сообщение об ошибке
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 году обновления безопасности отключили TLS 1.0 и 1.1 во всех поддерживаемых ветках JDK; с более старыми обновлениями тот же сервер работал.
Как исправить
- 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.
Крайняя мера: разрешите TLS 1.0/1.1 в одной изолированной JVM
Переопределение свойств безопасности, построенное на основе собственного значения 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