Получение SSLHandshakeException: handshake_failure несмотря на то, что мой клиент игнорирует все сертификаты - PullRequest
19 голосов
/ 22 марта 2012

У меня есть программа на Java, которая подключается к веб-серверу по протоколу SSL / TLS и отправляет различные HTTP-запросы по этому соединению.Сервер является локальным и использует самозаверяющий сертификат, но мой код использует пользовательские TrustManager и игнорирует недействительные сертификаты.До сих пор он работал отлично.

Единственное отличие на сервере состоит в том, что он работал для запуска jboss 6 и теперь работает под управлением jboss 7. Я не уверен, является ли это проблемой конфигурации, или есть липроблема с моим кодом, но я получаю те же ошибки, если пытаюсь подключиться с помощью других программ на Java, таких как WebScarab или ZAP.

В любом случае, могу ли я что-нибудь сделать с кодом, чтобы обойтиЭта проблема?Вот полная ошибка:

Received fatal alert: handshake_failure
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(Unknown Source)

Вот сообщения отладки до сбоя:

main, WRITE: TLSv1 Handshake, length = 75
main, WRITE: SSLv2 client hello message, length = 101
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1 ALERT: fatal, handshake_failure

Ответы [ 7 ]

25 голосов
/ 23 марта 2012

Итак, я нашел проблему. В Java может быть ошибка, но клиент, похоже, инициирует рукопожатие TLSv1, но затем отправляет приветственное сообщение клиента SSLv2, после чего сервер отклоняет соединение.

Это происходит, даже если вы создаете свой SSLContext с экземпляром TLS:

SSLContext sslContext = SSLContext.getInstance("TLS");

Решение состоит в том, чтобы установить системное свойство перед выполнением любых попыток подключения:

System.setProperty("https.protocols", "TLSv1");

Возможно, есть и другие решения, но этот работал для меня.

4 голосов
/ 29 января 2015

Было ли это когда-либо решено?

У меня была точно такая же проблема, по сути, я получал исключение рукопожатия сразу после clientHello.Итак, цепочка событий была

  1. Я бы представил свой сертификат серверу
  2. Сервер немедленно ответил бы ошибкой рукопожатия.(Я бы даже не вернул Server Hello).

В конце концов я обнаружил, что серверу требуется более сильный алгоритм шифрования / дешифрования, чем тот, который я предоставлял на начальной фазе рукопожатия (т. Е. Клиент иСервер не может договориться о алгоритме взаимного шифрования, который будет использоваться для связи ssl.

Мне нужно установить Unlimited Java JCE (Политику расширения криптографии Java).Существуют правила экспорта при использовании этого, поэтому, если вы отправляете свой код за границу, что может иметь последствия ... но это то, что решило мою проблему.

Эта ссылка объясняет, как установить обновленные политики http://suhothayan.blogspot.com/2012/05/how-to-install-java-cryptography.html

Это была также отличная ссылка, которая помогла мне точно понять, что происходит https://support.f5.com/kb/en-us/solutions/public/15000/200/sol15292.html#id

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

4 голосов
/ 23 марта 2012

Предоставляемой вами информации очень мало, равно как и трассировки стека.
Я сделаю здесь предположение.
Я подозреваю, что на новом сервере протокол TLSv1, в то время как ваши клиенты пытаются подключитьсяс SSLv3 (или меньше), и в результате рукопожатие терпит неудачу.

Поменяйте клиентов на использование более поздней версии TLS или
Сделайте так, чтобы ваш веб-сервер также поддерживал SSLv3.Я знаю, как сделать это в Tomcat, но не в JBoss.

Если это не сработает, обновите пост с дополнительной информацией (и полной трассировкой стека).
Вы должны включить ssl debug info -Djavax.net.debug=ssl

0 голосов
/ 16 января 2018

Для меня решение было: System.setProperty("https.protocols", "TLSv1.1,TLSv1.2");

0 голосов
/ 12 июня 2014

Я думаю, что это связано с Java 7 bug . Трудно быть уверенным без подробностей.

0 голосов
/ 23 марта 2012

Трассировка стека происходит от вашего клиентского кода и вашего клиента «Получено [фатальное предупреждение]» Другими словами, ошибка SSL произошла в Jboss, а не в вашем клиенте.

Поэтому пользовательские TrustManager на стороне клиента не имеют к этому никакого отношения. Я предполагаю, что ваш новый Jboss 7 настроен так, чтобы требовать сертификат клиента, а ваш клиент не представил ни одного.

Чтобы отладить ваше SSL-соединение, используйте openssl и попробуйте это:

openssl s_client -connect jboss.server.com:443

или это сервер SSLV3

openssl s_client -connect jboss.server.com:443 -ssl3

Это должно напечатать много интересной информации.

0 голосов
/ 23 марта 2012

Вы видите эту ошибку, скорее всего, потому что хранилище ключей, к которому у вашего JBoss 6 был доступ, не доступно вашему экземпляру JBoss 7.

Я бы порекомендовал следующее:

Ваш самоподписанный сертификат сервера должен быть импортирован в хранилище доверенных сертификатов

keytool -import -alias gridserver -file server.crt -storepass $YOUR_PASSWORD_HERE -keystore server.keystore

Добавьте следующие свойства в свой файл run.conf

-Djavax.net.ssl.keyStoreType=pkcs12
-Djavax.net.ssl.trustStoreType=jks
-Djavax.net.ssl.keyStore=clientcertificate.p12
-Djavax.net.ssl.trustStore=server.keystore
-Djavax.net.debug=ssl # very verbose debug. Turn this off after everything looks good.
-Djavax.net.ssl.keyStorePassword=$YOUR_PASSWORD_HERE
-Djavax.net.ssl.trustStorePassword=$YOUR_PASSWORD_HERE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...