ChangeCipherSpec - javax.net.ssl.SSLHandshakeException: получено фатальное предупреждение: handshake_failure

Я пытаюсь подключиться к URL-адресу https, на котором размещена служба SOAP, через SSL, используя HttpsURLConnection, когда получаю эту ошибку. По отладке в режиме SSL понимаю, что ClientHello, ServerHello, Certificate, ServerHelloDone, ClientKeyExchange успешно проходят. Исключение возникает только во время ответа сервера на этапе ChangeCipherSpec.

След отладки ssl выглядит следующим образом:

*** ClientHello, TLSv1.2
RandomCookie:  
GMT: 1456906493 
bytes = {<some-byte-data>}
Session ID:  {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_SHA]
Compression Methods:  { 0 }
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
Extension server_name, server_name: [host_name: www4.ipg-online.com]
Extension renegotiation_info, renegotiated_connection: <empty>
***
http-bio-8443-exec-5, WRITE: TLSv1.2 Handshake, length = 110
http-bio-8443-exec-5, READ: TLSv1.2 Handshake, length = 3951
*** ServerHello, TLSv1.2
RandomCookie:  
GMT: 1456906492 
bytes = {<some-byte-data>}
Session ID:  {198, 60, 71, 156, 166, 35, 121, 29, 184, 198, 218, 137, 212, 112, 9, 71, 249, 16, 69, 197, 109, 109, 113, 199, 214, 38, 187, 124, 229, 132, 43, 51}
Cipher Suite: SSL_RSA_WITH_RC4_128_SHA
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: <empty>
***
** SSL_RSA_WITH_RC4_128_SHA
*** Certificate chain
chain [0] = <this is the hostname certificate which is also present in my keystore>
chain [1] = <blah blah>
chain [2] = <blah blah>
***
Found trusted certificate:
[0] <blah blah> //this is that hostname certificate
*** CertificateRequest
Cert Types: 
RSA
, 
DSS

Supported Signature Algorithms: MD5withRSA, SHA1withRSA, SHA256withRSA
Cert Authorities: <cert details of the hostname cert found in keystore>
*** ServerHelloDone
*** Certificate chain
***
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1.2
http-bio-8443-exec-5, WRITE: TLSv1.2 Handshake, length = 289
SESSION KEYGEN:
PreMaster Secret: <some data>
CONNECTION KEYGEN:
Client Nonce: <some data>
Server Nonce: <some data>
Master Secret: <some data>
Client MAC write Secret: <some data>
Server MAC write Secret: <some data>
Client write key: <some data>
Server write key: <some data>
... no IV derived for this protocol
http-bio-8443-exec-5, WRITE: TLSv1.2 Change Cipher Spec, length = 21
*** Finished
verify_data:  {<some byte data>}
***
http-bio-8443-exec-5, WRITE: TLSv1.2 Handshake, length = 36
http-bio-8443-exec-5, READ: TLSv1.2 Alert, length = 22
http-bio-8443-exec-5
, RECV TLSv1.2 ALERT:  
fatal, 
handshake_failure
%% Invalidated:  [Session-2, SSL_RSA_WITH_RC4_128_SHA]
%% Invalidated:  [Session-3, SSL_RSA_WITH_RC4_128_SHA]
http-bio-8443-exec-5, called closeSocket()
http-bio-8443-exec-5, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert:   handshake_failure
http-bio-8443-exec-5, called close()
http-bio-8443-exec-5, called closeInternal(true)

Настройка моей среды

-Djavax.net.debug=ssl
-Djavax.net.ssl.keyStore=/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/security/cacerts
-Djavax.net.ssl.keyStorePassword=<password>
-Dhttps.cipherSuites=SSL_RSA_WITH_RC4_128_SHA

Код

Я использую groovy.

String path = "/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/security/cacerts"
char[] trustStorePassword = <password>.toCharArray();

InputStream trustStream = new FileInputStream(path);
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(trustStream, trustStorePassword);
trustStream.close()

TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(trustStore);
TrustManager[] trustManagers = trustFactory.getTrustManagers();
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, trustManagers, null);

URL url = new URL(<url-to-server>)
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
String userCredentials = "uname:passwd"
String basicAuth = "Basic " + new String(userCredentials.getBytes().encodeAsBase64())
con.setAllowUserInteraction(true)
con.setRequestProperty("Authorization", basicAuth);
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "text/xml");
con.setSSLSocketFactory(sslContext.getSocketFactory());
con.setDoOutput(true)

String urlParameters = "some-xml-data-as-string"
OutputStream wr = con.getOutputStream()
wr.write(urlParameters.getBytes("UTF-8"));
wr.flush();
wr.close();
int responseCode = con.getResponseCode(); //this is where i get exception

person devesh rastogi    schedule 12.09.2016    source источник
comment
Пожалуйста, предоставьте дополнительную информацию о вашей проблеме, код для вышеуказанного исключения необходим для отладки того, что происходит.   -  person SpiXel    schedule 12.09.2016
comment
@SpiXel добавил код.   -  person devesh rastogi    schedule 13.09.2016


Ответы (1)


... Исключение возникает только на этапе ChangeCipherSpec.

Предыдущие сообщения отсутствуют в вашем выводе, поэтому можно только догадываться: поскольку сервер отправляет предупреждение на последней фазе рукопожатия, то есть после согласования шифра и отправки сертификата сервером, наиболее вероятная причина заключается в том, что сервер имеет запросил у клиента сертификат, который клиент либо не предоставил, либо не понравился серверу. Возможно, вы найдете более подробную информацию в некоторых сообщениях журнала на стороне сервера.

person Steffen Ullrich    schedule 12.09.2016
comment
Я добавил всю трассировку отладки ssl. - person devesh rastogi; 13.09.2016
comment
@deveshrastogi: как и ожидалось: можно увидеть CertificateRequest с сервера, но клиент не отправляет запрошенный сертификат. - person Steffen Ullrich; 13.09.2016
comment
@deveshrastogi: если у вас нет клиентского сертификата, получите его. Если у вас есть один Как использовать SSL с самозаверяющий сертификат в Groovy? может помочь. Это то, что я обнаружил после нескольких секунд использования поисковой системы, лично у меня нет опыта работы с groovy. - person Steffen Ullrich; 13.09.2016