2016-09-12 10 views
2

このエラーが発生した場合、HttpsURLConnectionを使用してSSLを使用してSOAPサービスをホストするhttps URLに接続しようとしています。 SSLモードでのデバッグでは、 ClientHello, ServerHello, Certificate, ServerHelloDone, ClientKeyExchangeが正常に実行されることを理解しています。この例外は、サーバーの応答ChangeCipherSpecステージの間にのみ発生します。次のようにChangeCipherSpec - javax.net.ssl.SSLHandshakeException:致命的なアラートが受信されました:handshake_failure

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 

設定します。

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 
+0

あなたの問題に関する詳細情報を提供してください。何が起こっているのかをデバッグするには、上記の例外のコードが必要です。 – SpiXel

+0

@SpiXelがコードを追加しました。 –

答えて

1

...例外がChangeCipherSpecを段階のみ発生します。

以前のメッセージは出力に表示されないため、サーバーはハンドシェイクの最後の段階でアラートを送信します。つまり、暗号化がネゴシエートされ、サーバーが証明書を送信した理由は、サーバーが、クライアントが提供しなかった、またはサーバーが好まなかったクライアントから証明書を要求したことです。サーバー側のいくつかのログメッセージで詳細を見つけることができます。

+0

私はsslデバッグトレース全体を追加しました。 –

+0

@deveshrastogi:期待通り:サーバーからCertificateRequestを見ることができますが、クライアントは要求された証明書を送信していません。 –

+0

あなたは正しいです。それを解決するには? –

関連する問題