2015-03-14 5 views
4

Я использую Java 8 и запрос с SSLSocket этот адрес: https://www.flixbus.de/sites/default/files/6_jetzt_buchen_button_tiny.pngJava SSL SSLHandshakeException handshake_failure

Я всегда получаю ошибку рукопожатие. socket.setEnabledProtocols() для принудительного использования определенного протокола не помогло.

Btw, все остальные веб-серверы работают нормально. Так что это, вероятно, не связано с моим кодом.

Эта ошибка также возникает без ограничения протокола ssl/tls.

Любые идеи?

Выход с опцией «javax.net.debug = все» выглядит следующим образом:

DEBG getSecureScocket: Supported protocols: 
- SSLv2Hello 
- SSLv3 
- TLSv1 
- TLSv1.1 
- TLSv1.2 
DEBG getSecureScocket: Enabled protocols: 
- TLSv1.2 
Http Client, setSoTimeout(120000) called 
Allow unsafe renegotiation: false 
Allow legacy hello messages: true 
Is initial handshake: true 
Is secure renegotiation: false 

%% No cached client session 
*** ClientHello, TLSv1.2 
RandomCookie: GMT: 1426330417 bytes = { 229, 161, 185, 11, 136, 85, 35, 88, 166, 144, 191, 126, 10, 196, 215, 241, 43, 190, 221, 246, 240, 
217, 82, 29, 180, 106, 35, 253 } 
Session ID: {} 
Cipher Suites: [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_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_A 
ES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WIT 
H_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WIT 
H_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_12 
8_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV] 
Compression Methods: { 0 } 
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, 
secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r 
2, secp224k1, sect239k1, secp256k1} 
Extension ec_point_formats, formats: [uncompressed] 
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA25 
6withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA 
*** 
[write] MD5 and SHA1 hashes: len = 193 
[Raw write]: length = 198 
[Raw read]: length = 5 
[Raw read]: length = 2 
Http Client, READ: TLSv1.2 Alert, length = 2 
Http Client, RECV TLSv1.2 ALERT: fatal, handshake_failure 
Http Client, called closeSocket() 
Http Client, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 
Http Client, called close() 
Http Client, called closeInternal(true) 
Http Client, called close() 
Http Client, called closeInternal(true) 

Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 
     at sun.security.ssl.Alerts.getSSLException(Unknown Source) 
     at sun.security.ssl.Alerts.getSSLException(Unknown Source) 
     at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source) 
     at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source) 
     at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) 
     at sun.security.ssl.SSLSocketImpl.writeRecord(Unknown Source) 
     at sun.security.ssl.AppOutputStream.write(Unknown Source) 
     at java.io.OutputStream.write(Unknown Source) 
     [...] 
+0

Вы пробовали, позволяя все поддерживаемые протоколы, а не только TLSv1.2? просто чтобы убедиться, что это проблема (потому что, как вы, наверное, уже знаете, SSLvX больше не рекомендуется использовать в производстве) – morgano

+0

Да. Сначала я использовал настройки по умолчанию со всеми включенными протоколами. Не работает. Я нашел это решение [здесь] (http://stackoverflow.com/questions/4682957/why-does-javas-sslsocket-send-a-version-2-client-hello/4686924#4686924). Вот почему я ограничил протоколы и надеялся, что это поможет. –

ответ

6

Сайт требует SNI (server name indication), то есть без СНИ рукопожатие потерпит неудачу. Все современные браузеры поддерживают SNI, но не все стеки SSL в языках программирования поддерживают SNI или используют его по умолчанию. См http://www.vimino.com/2014/01/jep-114-tls-sni-extension-sunjsse-behavior-changes/ о том, как использовать SNI с Java 8.

Вы можете проверить для этого вида поведения с openssl s_client:

# without SNI 
$ openssl s_client -connect www.flixbus.de:443 
CONNECTED(00000003) 
140612985652896:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:770: 
.... 
New, (NONE), Cipher is (NONE) 

# with SNI 
$ openssl s_client -connect www.flixbus.de:443 -servername 'www.flixbus.de' 
CONNECTED(00000003) 
... 
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 

Или вы могли бы использовать analyze.pl:

$ perl analyze-ssl.pl www.flixbus.de 
-- www.flixbus.de port 443 
* maximum SSL version : TLSv1_2 (SSLv23) 
... 
* SNI supported  : SSL upgrade fails without SNI 
+0

Большое спасибо за указание на это (новое) расширение SNI. Это действительно решило проблему. –

+0

@ steffen-ullrich hi, если я запускаю ваш скрипт, я получаю «IO :: Socket :: SSL версии 1.984» - это только версия 1.31 в файле analyt-ssl.pl line 10.'. Любые подсказки для не-perler? – injecteer

+0

@ injecteer: Версия 1.31, которой вы пользуетесь, больше 5 лет, поэтому я думаю, вам почему-то нужно получить более новую версию. Если вы находитесь в окнах, последний Strawberry Perl должен включать то, что вам нужно. Если вы используете Linux, самые последние дистрибутивы содержат то, что вам нужно. –

0

Эта ошибка может быть сервер не поддерживает Tls1.2 использовать

+0

Я ограничился TLS1.2, потому что сервер отвечает TLS1.2. По крайней мере, это то, что я понимаю из журнала. Он также не работает, если я не делаю никаких ограничений по протоколу. –