SSLHandshakeException при подключении к сайту https

Я пытаюсь записать https- сайт через jmeter (версия 2.13, java-версия - 1.8u31), и я получаю исключение SSLHandshakeException при подключении к https-сайту. Сообщение об ошибке

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
    at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2011)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1113)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1363)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1391)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1375)
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:436)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
    at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294)
    at org.apache.jmeter.protocol.http.sampler.MeasuringConnectionManager$MeasuredConnection.open(MeasuringConnectionManager.java:107)
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:643)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
    at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.executeRequest(HTTPHC4Impl.java:517)
    at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sample(HTTPHC4Impl.java:331)
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:74)
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1146)
    at org.apache.jmeter.protocol.http.proxy.Proxy.run(Proxy.java:240)  

Я включил ведение журнала отладки для SSL, но я не смог понять основную причину. Кажется, что java-клиент отправляет ClientHello, но не получает сообщение ServerHello ( где сервер выбирает самую высокую версию SSL и лучший набор шифров, который поддерживается как клиентом, так и сервером, и отправляет эту информацию клиенту). Я вижу различия между версиями протокола, которые отправляются, читаются и принимаются клиентом (TLSv1.1 и TLSv1.2)

Это основная причина? Если так, как я могу это исправить?

Журналы вставляются сюда - Журналы Java SSLHandshakeException - Pastebin.com

Обновить

Как предложил @Anand Bhatt, я проанализировал сайт с помощью ssllabs и понял следующее

  1. Сервер не поддерживает TLSv1.2, который поддерживается Java 8
  2. Сервер поддерживает только один набор шифров - TLS_RSA_WITH_AES_256_CBC_SHA
  3. Java 8u31 не поддерживает набор шифров, который поддерживает сервер, и это, скорее всего, проблема.

Это звучит правильно? Если так, как мы можем заставить клиента java 8 поддерживать набор шифров, который поддерживает сервер?

1 ответ

Решение

SSLlabs, по-видимому, тестирует поддержку "из коробки". Java crypto имеет черепок, возникший в 1990-х годах, когда правительство США строго ограничило экспорт криптографического программного обеспечения, и в результате JRE (или JDK), распространяемый тогдашним Sun-Oracle, не позволяет использовать 256-битное симметричное шифрование, который требует ваш сервер. Вы должны загрузить и установить "Файлы политики неограниченной юрисдикции JCE " для вашей основной (Java) версии; 8 находится по адресу http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html. README в файле содержит подробные сведения, но в основном вы заменяете два крошечных файла JAR в JRE / lib / security.

TLSv1.2 не является реальной проблемой сейчас. Протокол TLS автоматически согласовывает самую высокую версию, поддерживаемую (и включаемую) обоими сторонами. Java 8 реализует SSLv3, TLSv1.0, TLSv1.1 и TLSv1.2, но недавние обновления (8u31 или 7u75 и выше) по умолчанию отключают SSLv3 из-за POODLE; Вы можете включить его, если захотите, но вам не хотелось бы. (Java 7 реализует те же версии протокола, но клиент по умолчанию отключает 1.1 и 1.2 из-за проблем совместимости при его выпуске несколько лет назад.)

Однако из-за POODLE и BEAST некоторые органы безопасности больше не принимают SSLv3 и TLSv1.0 как достаточно безопасные; Важным примером являются кредитные и дебетовые карты, как описано в https://security.stackexchange.com/a/87077/39571. TLSv1.2 включает некоторые технические улучшения по сравнению с 1.1, что делает его предпочтительным сегодня, и могут быть будущие открытия, которые сделают эти улучшения критическими; если ваш сервер не может поддерживать 1.2 (и, возможно, выше) в этот момент, у вас будут проблемы. Точно так же тот факт, что единственный поддерживаемый серверный набор использует простой обмен ключами RSA, т.е. НЕ обеспечивает прямую секретность, в настоящее время считается неоптимальным и со временем может стать неприемлемым.

keytool (по крайней мере с обычно используемыми файлами хранилищ ключей и доверенных сертификатов) не имеет ничего общего с симметричной криптографией. Вероятно, это может иметь значение, если сервер использует корень ЦС (или, точнее, чуть более общий, якорь доверия), которому не доверяет ваша JRE и / или приложение, и / или если сервер хочет аутентификацию клиента на уровне SSL/TLS, что довольно редко. (Большинство веб-сайтов проходят проверку подлинности на уровне веб-приложений или, по крайней мере, на уровне HTTP.) Проверка SSLLabs цепочки сертификатов сервера (и некоторых других вещей), как правило, строже, чем у Java, и они не жаловались на это. площадь, так что вряд ли у вас там проблемы.

Другие вопросы по тегам