2008-12-17 11 views
8

जावा यूआरएल वर्ग का उपयोग करके, मैं बाहरी HTTPS सर्वर (जैसे हमारी उत्पादन साइट) से कनेक्ट कर सकता हूं, लेकिन एक स्थानीय यूआरएल का उपयोग करके मुझे निम्नलिखित अपवाद मिलते हैं।मैं जावा में स्थानीय HTTPS यूआरएल का उपयोग कैसे करूं?

"SunCertPathBuilderException: unable to find valid certification path to requested target". 

मुझे वैध प्रमाणीकरण पथ कैसे प्राप्त होगा?

संपादित करें: मैं सीधे एक कनेक्शन बनाने के लिए इस यूआरएल का उपयोग नहीं कर रहा हूं, मैं itextPDFReader पर यूआरएल पास कर रहा हूं, जिसके बाद कनेक्शन समस्या है।

उत्तर

12

यहां मेरा समाधान था जो इस धागे में कुछ विचारों को शामिल करता है और नेट के चारों ओर कोड के साथ चिपकाया जाता है। मैं इस फ़ंक्शन को कॉल करता हूं और यह HttpsURLConnection के लिए डिफ़ॉल्ट ट्रस्ट प्रबंधक और होस्टनाम सत्यापनकर्ता सेट करता है। यह कुछ के लिए अवांछनीय हो सकता है क्योंकि यह सभी HttpsURLConnections को प्रभावित करेगा लेकिन मैं सिर्फ एक साधारण प्रॉक्सी लिख रहा हूं इसलिए यह मेरे लिए काम करता है।

private void setTrustAllCerts() throws Exception 
{ 
    TrustManager[] trustAllCerts = new TrustManager[]{ 
     new X509TrustManager() { 
      public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
       return null; 
      } 
      public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { } 
      public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) { } 
     } 
    }; 

    // Install the all-trusting trust manager 
    try { 
     SSLContext sc = SSLContext.getInstance("SSL"); 
     sc.init(null, trustAllCerts, new java.security.SecureRandom()); 
     HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 
     HttpsURLConnection.setDefaultHostnameVerifier( 
      new HostnameVerifier() { 
       public boolean verify(String urlHostName, SSLSession session) { 
        return true; 
       } 
      }); 
    } 
    catch (Exception e) { 
     //We can not recover from this exception. 
     e.printStackTrace(); 
    } 
} 
+0

धन्यवाद कॉर्नपफ - यह काफी सही है जिस कोड को मैंने लिखना समाप्त कर दिया है (हालांकि मैंने इसे थोड़ी देर पहले किया था)। – RodeoClown

0

समस्या यह शिकायत कर रही है कि जब आप कोई SSL कनेक्शन बनाते हैं, तो सर्वर को क्लाइंट को एक वैध प्रमाणपत्र प्रस्तुत करना होगा। आप जावा में एक उचित एंडपॉइंट लिख सकते हैं (HTTPServerSocket मुझे ऐसा लगता है) लेकिन इसे सेट करने के बारे में कुछ हैकिंग की आवश्यकता होगी। एसएसएल को सही तरीके से संभालते हुए किसी भी स्थानीय वेब सर्वर को स्थापित करना संभवतः आसान है --- अपाचे, लाइटटैप, जो कुछ भी --- और openssl टूल का उपयोग करके एक स्व-हस्ताक्षरित प्रमाणपत्र बनाएं।

अपडेट

जावा अल्मनैक से यहां एक उदाहरण दिया गया है। http://www.exampledepot.com/egs/javax.net.ssl/Server.html

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

> java -Djavax.net.ssl.keyStore=mySrvKeystore -Djavax.net.ssl.keyStorePassword=123456 MyServer 
+0

मैं एक काम कर HTTPS सर्वर चल रहा है, मैं सिर्फ जावा यूआरएल वर्ग के साथ उससे कनेक्ट कर सकते नहीं (मुख्य पोस्ट करते समय इस प्रतिबिंबित करने के लिए) – RodeoClown

3

आप शायद सेटअप एक HostnameVerifier की जरूरत है:

try { 
    int port = 443; 
    ServerSocketFactory ssocketFactory = SSLServerSocketFactory.getDefault(); 
    ServerSocket ssocket = ssocketFactory.createServerSocket(port); 

    // Listen for connections 
    Socket socket = ssocket.accept(); 

    // Create streams to securely send and receive data to the client 
    InputStream in = socket.getInputStream(); 
    OutputStream out = socket.getOutputStream(); 

    // Read from in and write to out... 

    // Close the socket 
    in.close(); 
    out.close(); 
} catch(IOException e) { 
} 

javax.net.ssl.keyStore प्रणाली संपत्ति का उपयोग कर प्रमाण पत्र की कुंजीस्टोर निर्दिष्ट करें। कनेक्ट करने से पहले, आपको कनेक्शन ऑब्जेक्ट

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); 
conn.setHostnameVerifier(new HostnameVerifier() { 
    public boolean verify(String hostname, SSLSession session) { 
    // check hostname/session 
    return true; 
    } 
}); 
conn.connect(); 
// read/write... 

वहां निश्चित रूप से कुछ कार्यान्वयन हैं, यदि आपको एक की आवश्यकता है। आप HttpClient प्रोजेक्ट को भी देखना चाहेंगे।

+0

मैं इस का उपयोग किया है, धन्यवाद! – RodeoClown

3

TrustManager पर आप देख रहे हैं एक और बात यह है कि आप उपयोग कर रहे हैं। त्रुटि संदेश से पता चलता है कि सर्वर द्वारा प्रस्तुत प्रमाण पत्र किसी विश्वसनीय रूट द्वारा हस्ताक्षरित नहीं है। चूंकि आपके द्वारा बनाई गई SSL सॉकेट पर प्रत्यक्ष नियंत्रण नहीं है, इसलिए मुझे लगता है कि आपकी सर्वश्रेष्ठ शर्त initializeTrustManager के साथ है जो सर्वर की प्रमाणपत्र श्रृंखला के setup with the root CA है। फिर इस संदर्भ को default के रूप में सेट करें।

यह माना जाता है कि आप जावा 6 का उपयोग कर रहे हैं। एपीआई जावा 5 में अधिक सीमित है। आप डिफ़ॉल्ट SSLSocketFactory प्राप्त कर सकते हैं, लेकिन इसे सेट करने का कोई मानक तरीका नहीं है।

0

यह आपको उस प्रमाणपत्र को जोड़ने में भी मदद कर सकता है जो स्थानीयहोस्ट सर्वर का उपयोग कर रहा है (मुझे लगता है कि यह स्वयं हस्ताक्षरित है) JVM के keystore, using the "keytool" utility पर। इसका JVM कहने का प्रभाव होना चाहिए "आप इस प्रमाणपत्र पर भरोसा कर सकते हैं"।

0

मैंने एक स्थिर विधि (केवल dev पर) चलाया है जो एक बहुत ही भरोसेमंद ट्रस्टमैनेजर (सब कुछ स्वीकार करता है) स्थापित करता है, और एक होस्टनाम वर्रिफायर भी जोड़ा जाता है जो हमेशा सत्य देता है (धन्यवाद sblundy)।

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