Причина javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

204
27 ноября 2021, 10:50

Есть веб-приложение, крутящееся на JVM.

Возникла необходимость интеграции с сторонней системой.

И все вроде бы ничего, но при подключении на продуктивный контур, возникает следующее исключение

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

Я уже спрашивал это здесь.

Но данное исключение может быть по множеству причин.

Сертификаты в cacerts установлены, однако, ошибка не ушла.

Долго думая, я пришел к выводу, что это из-за того, что на продуктивном контуре стоит SSL сертификат с ГОСТ шифрованием.

Прикол в том, что если установить эти сертификаты на локальную машину Windows в хранилище сертификатов и попытаться зайти на продуктив через IE, то все работает. Заходим через хром - видим.

Failed to load resource: net::ERR_SSL_VERSION_OR_CIPHER_MISMATCH

Адрес прода совсем не секрет - http://egrz.ru/ и тык на личный кабинет

Т.е. когда мы пытаемся обратиться по адресу, если Cipher suites клиента не содержит Cipher suite сервера, мы получаем исключение.

Мои Ciphers(ничего, содержащего "GOST" нет):

Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]

Поправьте, если неправ.

Но как все-таки обойти это?

Возможно, можно попробовать через OpenSSL. Тут обсуждается данная тема. Но вот беда - интеграцию Java и OpenSSL (чисто для создания SSL подключения) я не представляю.

Возможно, КриптоПро JCP реализует данные Cipher suites (вплоть до новых ГОСТов, вплоть до кузнечика), но денег в компании нема. Хотя мб и раскошелимся.

Кто-нибудь сталкивался с подобным?

Если кто-то решил это при помощи КриптоПро JCP, то у меня всего-лишь один вопрос - есть ли там методы, которые помогут переопределить создание SSL подключения в Apache HTTP client? Кода очень-очень-очень много, переписывать все очень не хочется (первоначально все писалось для тестового контура, в котором вообще ssl нет).

А так же есть ли другие способы реализации и правильны ли мои догадки по поводу ciphers?

Заранее спасибо

Answer 1

Я сталкивался с подобной проблемой, но прямого решения (без установки стороннего софта) я не нашел. Однако способ обойти все таки есть (попробуйте, возможно хотя бы поймете в чем проблема):

  1. На машине с JVM ставите Fiddler
  2. Запускаете Fiddler
  3. Заворачиваете трафик вашего приложения в Fiddler любым из способов

В результате трафик вашего приложения будет идти через прокси Fiddlerа и выглядеть как "от браузера". Вместо фидлера (его основное назначение - дебаггинг) вы можете использовать любое похожее ПО, главное чтобы трафик шел через прокси.

READ ALSO
Java Android аналог file_get_contents как в php

Java Android аналог file_get_contents как в php

Есть ли в Java для андроида что то похожее на file_get_contents()  как в PHPДело в том что я хочу взять код с   html страницы применить специальную кодировку...

204
Дождаться завершения работы второго потока

Дождаться завершения работы второго потока

Есть слушатель в главном потоке, он должен ждать ответа из другого потокаВот пример:

71
Как передать список MultipartFile в контроллер?

Как передать список MultipartFile в контроллер?

У меня есть такой контроллер (поменять его не могу):

201