2012-03-22 9 views
19

मैं एक जावा प्रोग्राम एक वेबसर्वर SSL/TLS का उपयोग कर को जोड़ता है, और कहा कि कनेक्शन पर विभिन्न HTTP अनुरोध भेजता है है अनदेखी के बावजूद handshake_failure। सर्वर लोकलहोस्ट है और एक स्व-हस्ताक्षरित प्रमाणपत्र का उपयोग कर रहा है, लेकिन मेरा कोड कस्टम ट्रस्टमेनर्स का उपयोग कर रहा है, और अमान्य प्रमाणपत्रों को अनदेखा करता है। यह अब तक पूरी तरह से काम किया है।प्राप्त SSLHandshakeException: मेरे मुवक्किल सभी प्रमाणपत्र

सर्वर पर एकमात्र अंतर यह है कि यह jboss 6 चलाने के लिए प्रयुक्त होता है और अब यह jboss 7 चला रहा है। मुझे यकीन नहीं है कि यह एक कॉन्फ़िगरेशन समस्या है, या क्या मेरे कोड में कोई समस्या है, लेकिन मुझे मिलता है यदि मैं अन्य जावा-आधारित प्रोग्राम्स जैसे 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 

उत्तर

24

तो मुझे समस्या मिली। जावा में एक बग हो सकता है, लेकिन क्लाइंट एक टीएलएसवी 1 हैंडशेक शुरू करने लगता है, लेकिन उसके बाद एक एसएसएलवी 2 क्लाइंट हैलो संदेश भेजता है, जिस बिंदु पर सर्वर कनेक्शन को अस्वीकार करता है।

यह तब होता है, भले ही आप टीएलएस का एक उदाहरण के साथ अपने SSLContext बनाएँ:

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

समाधान एक प्रणाली गुण सेट करने के लिए है से पहले किसी तरह के संबंध का प्रयास किया जाता है:

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

शायद रहे हैं इसके अन्य समाधान, लेकिन यह मेरे लिए काम किया।

+1

आपको इसमें रुचि हो सकती है: http://stackoverflow.com/a/4686924/372643 – Bruno

+0

@ ब्रूनो हाँ, मैंने देखा कि पहले Google को खोजते समय। क्या यह जावा में एक बग है? जब मैं SSLContext को TLS के रूप में निर्दिष्ट करता हूं तो मैं नहीं देख सकता कि यह डिफ़ॉल्ट व्यवहार कैसे हो सकता/सकती है। – Rsaesha

+1

यह एक बग नहीं है, यह डिज़ाइन द्वारा है (एसएसएलवी 2 पिछड़ा कंप के लिए है।)। [जेएसएसई रेफ/एसएसएल कॉन्टेक्स्ट] देखें (http://docs.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#SSLContext): "* उदाहरण के लिए, getInstance (" SSLv3 ") एक उदाहरण लौटा सकता है जो "एसएसएलवी 3" और "टीएलएसवी 1" * लागू करता है [...] आप सेट कर सकते हैं कि कौन से प्रोटोकॉल वास्तव में एक एसएसएल कनेक्शन के लिए विधि सेटएन्टेबल प्रोटोकॉल (स्ट्रिंग [] प्रोटोकॉल) का उपयोग करके सक्षम हैं "। आपके मामले में, 'https.protocols' 'HttpsURLConnection' के लिए 'setEnabledProtocols' का ख्याल रखता है। – Bruno

0

आप सबसे शायद यह त्रुटि देख रहे हैं, क्योंकि कुंजीस्टोर कि आपके JBoss 6 तक पहुँच थी सुलभ नहीं है आपके जेबॉस 7 उदाहरण के लिए।

मैं जो सिफारिश करता हूं वह निम्नलिखित है।

आपका स्व-हस्ताक्षरित सर्वर प्रमाणपत्र में truststore

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

सर्वर Chrome या Firefox जैसे एक वेब ब्राउज़र के माध्यम से ठीक चलाता है, तो सर्वर पर कुंजीस्टोर मुद्दा नहीं है। प्रमाणन या तो कोई मुद्दा नहीं होना चाहिए, क्योंकि मैं बस सभी कर्टों को अनदेखा कर रहा हूं। – Rsaesha

4

की जानकारी उपलब्ध कराने के लिए बहुत कम अपने रूप में भी है स्टैक ट्रेस।
मैं यहां अनुमान लगाऊंगा।
क्या मुझे लगता है कि नए सर्वर में प्रोटोकॉल TLSv1 है, जबकि अपने ग्राहकों SSLv3 (या कम) के साथ और एक परिणाम के हाथ मिलाना विफल रहता है के रूप में कनेक्ट करने का प्रयास है।

आपको क्लाइंट को टीएलएस या
के उच्च संस्करण का उपयोग करने के लिए बदलें, अपने वेबसर्वर को SSLv3 का भी समर्थन करें। मुझे पता है कि यह टोमकैट में कैसे करें लेकिन जेबॉस में नहीं।

इस बारे में अधिक जानकारी (और एक पूर्ण स्टैक ट्रेस) के साथ पोस्ट अद्यतन काम नहीं करता है।
आप SSL डिबग जानकारी -Djavax.net.debug=ssl

+0

पूर्ण स्टैक ट्रेस बस मेरी कक्षा की कनेक्शन विधि दिखाता है, और जो भी तरीके उसे कॉल करता है। यह वही तरीका है जो सर्वर के पिछले संस्करणों के साथ काम कर रहा है। वैसे भी, यहां डीबग है: http://pastebin.com/RJqcQwaP मुझे थोड़ा अजीब लगता है कि भले ही मैं अपने प्रोग्राम को टीएलएस का उपयोग करने के लिए कहूं, ऐसा लगता है कि यह एसएसएलवी 2 क्लाइंट हैलो संदेश भेजना चाहता है । – Rsaesha

+0

@Rsaesha: – Cratylus

0

सक्षम होना चाहिए स्टैक ट्रेस आप ग्राहक कोड और आपके ग्राहक 'प्राप्त [एक] घातक चेतावनी' से है। दूसरे शब्दों में, एसएसएल त्रुटि जेबॉस में हुई, न कि आपके ग्राहक।

इसलिए आपके ग्राहक पक्ष कस्टम ट्रस्टमेनर्स के पास इसके साथ कुछ लेना देना नहीं है। मेरा जंगली अनुमान यह है कि आपका नया जेबॉस 7 क्लाइंट प्रमाण पत्र की आवश्यकता के लिए कॉन्फ़िगर किया गया है और आपके क्लाइंट ने कोई भी प्रस्तुत नहीं किया है।

अपने SSL कनेक्शन डिबग करने के लिए, openssl उपयोग करें और यह प्रयास करें:

openssl s_client -connect jboss.server.com:443

या यह एक SSLv3 सर्वर

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

यह रोचक जानकारी का एक बहुत प्रिंट चाहिए है।

+0

पोस्ट में कुछ क्लाइंट कोड डालें यहां पहली कमांड का आउटपुट है: http://pastebin.com/NvRqdu3f – Rsaesha

+0

मेरा जंगली अनुमान बस जंगली था। आपका सर्वर ठीक है। user384706 आपको सही रास्ते पर मिला। प्रोटोकॉल संस्करण विसंगति की संभावना अधिक है। मुझे लगता है कि आपका सर्वर TLSv1/SSLv3 है और आप SSLv2 भेज रहे हैं। –

0

मुझे लगता है कि यह Java 7 bug से संबंधित है। अधिक जानकारी के बिना सुनिश्चित करना मुश्किल है।

4

क्या यह कभी हल किया गया था?

मुझे एक ही समस्या थी, अनिवार्य रूप से मुझे क्लाइंट हैलो के तुरंत बाद एक हैंडशेक अपवाद प्राप्त हो रहा था। तो घटनाओं की श्रृंखला

  1. था मैं सर्वर
  2. सर्वर तुरंत एक हाथ मिलाना विफलता के साथ जवाब देगा करने के लिए अपने प्रमाण पत्र प्रस्तुत करेगा। (मुझे एक सर्वर हैलो वापस भी नहीं मिलेगा)।

आखिरकार मैंने पाया कि सर्वर मैं क्या प्रारंभिक हाथ मिलाना चरण में आपूर्ति किया गया था (ie। क्लाइंट और सर्वर SSL संचार के लिए उपयोग करने के लिए एक आपसी एन्क्रिप्शन एल्गोरिथ्म पर सहमत नहीं हो सकता है की तुलना में एक मजबूत एन्क्रिप्शन/डिक्रिप्शन एल्गोरिथ्म की जरूरत थी)।

मुझे असीमित जावा जेसीई (जावा क्रिप्टोग्राफी एक्सटेंशन नीति) स्थापित करने की आवश्यकता है। इसका उपयोग करने पर निर्यात नियम हैं, इसलिए यदि आप विदेश में अपना कोड भेजते हैं, तो इसका असर हो सकता है..यह भी मेरी समस्या का समाधान करता है।

यह लिंक अपडेट की गई नीतियों 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

चल रहा था मदद की स्थापित करने के लिए कैसे बताते हैं, लेकिन जब ग्राहक हैलो के तुरंत बाद हैंडशेक विफल हो जाता है, तो यह क्लाइंट की तरह दिखता है और सर्वर किसी चीज़ पर सहमत नहीं हो सकता है (कई मामलों में यह एन्क्रिप्शन एल्गोरिदम है कि उन्हें पारस्परिक रूप से संवाद करने की आवश्यकता होगी)।

0

मेरे लिए समाधान था: System.setProperty("https.protocols", "TLSv1.1,TLSv1.2");

संबंधित मुद्दे