5

मैं बुनियादी लेख के साथ एक आरामदायक डब्ल्यूएस का उपभोग करने की कोशिश कर रहा हूं। मैंने अपने कीस्टोर में कोई प्रमाण नहीं आयात किया। जब मैं क्रोम प्लगइन Advance Rest client का परीक्षण करने के लिए उपयोग करता हूं (बेस 64 एन्कोडेड उपयोगकर्ता नाम: पास के साथ मूल ऑथ का उपयोग करके)। मैं प्रतिक्रिया वापस देख सकता हूँ। अब तक सब ठीक है। लेकिन जब मैं इस ws उपभोग करने के लिए जावा कोड विकसित करने, मैं SSL handsake विफलता मिलती है:स्प्रिंग रेस्ट टेम्पलेट: एसएसएल हैंडशेक विफलता

org.springframework.web.client.ResourceAccessException: I/O error: 
Received fatal alert: handshake_failure; nested exception is 
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:453) 
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:401) 
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:377) 
at test.Rest.main(Rest.java:37) Caused by: 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) 

मेरा प्रश्न है: समस्या है अगर क्योंकि मैं अपने कीस्ट्रोक को प्रमाणपत्र आयात नहीं किया, तो दोनों जावा कोड और प्लगइन चाहिए एक साथ काम नहीं करते हैं। यहां, प्लगइन काम करता है लेकिन मेरा कोड नहीं करता है। कारण क्या है? मेरे कोड के साथ कुछ गलत है?

Bellow मेरी कोड

RestTemplate restTemplate = new RestTemplate();   
String plainCreds = "username:pass"; 
byte[] plainCredsBytes = plainCreds.getBytes(Charset.forName("US-ASCII"));  
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes); 
String base64Creds = new String(base64CredsBytes); 

HttpHeaders headers = new HttpHeaders(); 
headers.add("Authorization", "Basic " + base64Creds); 

ResponseEntity<String> response = 
      restTemplate.exchange("https://url",HttpMethod.GET,new 
            HttpEntity(headers),String.class); 

है यहाँ लॉग फ़ाइल के लिए लिंक है: (मैं XXXXXX के आधार पर अपने सर्वर-नाम की जगह है) http://www.filedropper.com/ssllog

चलाने के बाद: openssl s_client -showcerts -tls1 - कनेक्ट मेजबान: जब मैं आदेश चला बंदरगाह

WARNING: can't open config file: /usr/local/ssl/openssl.cnf 
CONNECTED(00000164) 
8088:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:.\ssl\s3_pkt.c:362: 
--- 
no peer certificate available 
--- 
No client certificate CA names sent 
--- 
SSL handshake has read 5 bytes and written 0 bytes 
--- 
New, (NONE), Cipher is (NONE) 
Secure Renegotiation IS NOT supported 
Compression: NONE 
Expansion: NONE 
No ALPN negotiated 
SSL-Session: 
    Protocol : TLSv1 
    Cipher : 0000 
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 
    Key-Arg : None 
    PSK identity: None 
    PSK identity hint: None 
    SRP username: None 
    Start Time: 1452011344 
    Timeout : 7200 (sec) 
    Verify return code: 0 (ok) 
--- 

और इस उत्पादन है openssl s_client -connect सर्वर: बंदरगाह

WARNING: can't open config file: /usr/local/ssl/openssl.cnf 
CONNECTED(00000164) 
depth=0 C = US, ST = "XXXXXX", L = XXXXXX, O = XXXXXX, OU = xxxxx, CN = XXXXXXXXX.test.intranet, emailAddress = [email protected] 
verify error:num=20:unable to get local issuer certificate 
verify return:1 
depth=0 C = US, ST = "XXXXXXX ", L = XXXXX, O = XXXXXX, OU = xxxxxx, CN = XXXXXXXXX.test.intranet, emailAddress = [email protected] 
verify error:num=21:unable to verify the first certificate 
verify return:1 
--- 
Certificate chain 
0 s:/C=US/ST=XXXXXXX /L=XXXXX/O=XXXXXX/OU=XXXXX/CN=XXXXXX.test.intranet/[email protected] 
    i:/DC=intranet/DC=xxxx/CN=XXXXXX DEV Issuing CA 
--- 
Server certificate 
-----BEGIN CERTIFICATE----- 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 
XXXXX..... 
-----END CERTIFICATE----- 
subject=/C=US/ST=XXXXXXX /L=XXXXX/O=XXXXXX/OU=XXXXX/CN=XXXXXX.test.intranet/[email protected] 
issuer=/DC=intranet/DC=XXX/CN=XXXXX DEV Issuing CA 
--- 
No client certificate CA names sent 
Peer signing digest: SHA512 
Server Temp Key: XXXXX, P-256, 256 bits 
--- 
SSL handshake has read 1895 bytes and written 443 bytes 
--- 
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 
Server public key is 2048 bit 
Secure Renegotiation IS supported 
Compression: NONE 
Expansion: NONE 
No ALPN negotiated 
SSL-Session: 
    Protocol : TLSv1.2 
    Cipher : ECDHE-RSA-AES128-GCM-SHA256 
    Session-ID: 568BF22A5CDBF103155264BBC056B272168AE0777CBC10F055705EB2DD907E5A 
    Session-ID-ctx: 
    Master-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 
    Key-Arg : None 
    PSK identity: None 
    PSK identity hint: None 
    SRP username: None 
    Start Time: 1452012074 
    Timeout : 300 (sec) 
    Verify return code: 21 (unable to verify the first certificate) 
--- 
read:errno=0 
+0

क्रोम और आपका ऐप्लिकेशन विभिन्न जावा का उपयोग कर सकते हैं और इसलिए अलग सेटिंग हो। यहां तक ​​कि यदि जावा समान है तो लाखों कारण हैं कि यह क्यों काम नहीं करता है। हालांकि यह अच्छी शुरुआत है कि यह क्रोम से काम करता है। JVM के SSL डीबग को सक्षम करें, उदाहरण के लिए: '-Djavax.net.debug = ssl जोड़ें: हैंडशेक: वर्बोज़' और अपने प्रश्न में आउटपुट जोड़ें, अतिरिक्त डीबग तर्क यहां उपलब्ध हैं http://docs.oracle.com/javase/7/ दस्तावेज़/टेक्नोट्स/गाइड/सुरक्षा/जेएसई/जेएसएसईआरजीयूयूइड.html # डीबग –

+0

मैं आपके सर्वर की जांच करूंगा, क्योंकि लॉग में 'सर्वरहेल्लो' संदेश नहीं है जैसे आपका सर्वर एसएसएल नहीं चला रहा था। यदि आपने openssl को 'openssl s_client -showcerts -tls1 -connect [your_host] से कनेक्ट करने का प्रयास किया है: [port] '। यह भी देखें http://www.smartjava.org/content/how-analyze-java-ssl-errors –

+0

धन्यवाद मीकल। मैंने openssl चलाने के लिए आउटपुट जोड़ा है। क्रिप्या मेरि सहायता करे। मैं एसएसएल और सर्टिफिकेट स्टफ – David

उत्तर

7

javax.net.debug लॉग से मैं देख सकता हूं कि आप जावा 7 का उपयोग कर रहे हैं और क्लाइंट TLSv1 को हल करता है। openssl आउटपुट से कि आपका सर्वर TLSv1 का समर्थन नहीं करता है।

TLS ver. 1.1 and 1.2 are disabled in Java 7 by default.

हालांकि जावा SE 7 रिलीज में SunJSSE TLS 1.1 और TLS 1.2 का समर्थन करता है, न तो संस्करण ग्राहक कनेक्शन के लिए डिफ़ॉल्ट रूप से सक्षम है। कुछ सर्वर आगे संगतता को सही ढंग से कार्यान्वित नहीं करते हैं और टीएलएस 1.1 या टीएलएस 1.2 क्लाइंट से बात करने से इनकार करते हैं। इंटरऑपरेबिलिटी के लिए, सनजेएसएसई क्लाइंट कनेक्शन के लिए डिफ़ॉल्ट रूप से टीएलएस 1.1 या टीएलएस 1.2 सक्षम नहीं करता है।

TLSv1.1 और TLSv1.2 या तो द्वारा सक्षम करें:

  1. JVM तर्क:

    -Dhttps.protocols=TLSv1.2,TLSv1.1,TLSv1 
    
  2. या जावा कोड से एक ही गुण सेट:

    System.setProperty("https.protocols", "TLSv1.2,TLSv1.1,TLSv1"); 
    
  3. या JCE Unlimited Strength policy files for Java 7 स्थापित करें। मैं 100% निश्चित नहीं हूं कि यह एकल चरण समस्या का समाधान करेगा हालांकि यह हमेशा जेसीई स्थापित करने के लायक है, जबकि यह JVM को मौजूदा एल्गोरिदम के मजबूत संस्करणों का उपयोग करने की अनुमति देता है।

अद्यतन 29/Sep/2016:

परिवर्तित विकल्प 1 और 2 में बेहतर से बदतर से प्रोटोकॉल का आदेश (TLS ver 1 करने के लिए 1.2।)।

+0

धन्यवाद आपके मरीज के लिए माइकल मेरी मदद करने के लिए। हम पाते हैं कि सर्वर जो बाकी ws होस्ट करता है jdk8 का उपयोग कर रहा है, और मेरा क्लाइंट jdk7 का उपयोग कर रहा है। तो हमने सर्वर को jdk7 में डाउनग्रेड कर दिया है। और मुझे -dhttps.protocols = TLSv1, TLSv1.1, TLSv1.2 का उपयोग कर टीएसएलवी 1.2 का उपयोग करने के लिए जेडीके को भी मजबूर करना होगा। यह अब काम कर रहा है। – David

+0

का उपयोग करने से पहले -Dhttps.protocols = TLSv1, TLSv1.1, TLSv1.2 का उपयोग करने से पहले। मैंने jdk7 के लिए जेसीई असीमित शक्ति नीति स्थापित करने का भी प्रयास किया। मैंने ज़िप फ़ाइल में फ़ाइलों द्वारा jdk/jre/lib/security में फ़ाइलों को प्रतिस्थापित किया है। लेकिन यह काम नहीं करता है। – David

+0

आपका स्वागत है डेविड और आपकी प्रतिक्रिया और प्रशंसा के लिए धन्यवाद। –

1

यदि आप जावा 7 का उपयोग करते हैं तो आपको स्पष्ट रूप से जावा को TLSv1.2 प्रोटोकॉल का उपयोग करने के लिए कहने की आवश्यकता है। स्प्रिंग एक्सएमएल कॉन्फ़िगरेशन का उपयोग करके यहां एक उदाहरण दिया गया है।

***In any Spring bean (i.e. a controller)*** 

import org.apache.http.client.HttpClient; 
import org.apache.http.ssl.SSLContexts; 
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 
import org.apache.http.impl.client.HttpClients; 
import javax.net.ssl.SSLContext; 

@Bean(name="client") 
public HttpClient make() throws NoSuchAlgorithmException, KeyManagementException { 
    SSLContext sslContext = SSLContexts.custom().build(); 
    SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, 
      new String[]{"TLSv1.2", "TLSv1.1"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier()); 
    return HttpClients.custom() 
      .setSSLSocketFactory(sslConnectionSocketFactory) 
      .build(); 
} 

***In XML configuration files*** 

<bean id="factory" 
     class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory"> 
    <property name="httpClient" ref="client"/> 
</bean> 
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate"> 
    <property name="requestFactory" ref="factory"/> 
</bean> 

आप कुछ इस तरह के साथ एक्सएमएल बिना ही कर सकता है:

RestTemplate restTemplate; 

public HttpClient getHttpClient() throws NoSuchAlgorithmException, KeyManagementException { 
    SSLContext sslContext = SSLContexts.custom().build(); 
    SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, 
      new String[]{"TLSv1.2", "TLSv1.1"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier()); 
    return HttpClients.custom() 
      .setSSLSocketFactory(sslConnectionSocketFactory) 
      .build(); 
} 

public void setUp() throws Exception { 
    restTemplate = new RestTemplate(
      new HttpComponentsClientHttpRequestFactory(
        getHttpClient())); 
    ... 
} 
संबंधित मुद्दे