2012-01-30 9 views
5

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

public class A{ 
    HostnameVerifier hv = new HostnameVerifier(){ 
     public boolean verify(String urlHostName, SSLSession session){ 
      return true; 
     }  
    }; 

    HttpsURLConnection.setDefaultHostnameVerifier(hv); 

    javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1]; 
    javax.net.ssl.TrustManager tm = new miTM(); 
    trustAllCerts[0] = tm; 
    javax.net.ssl.SSLContext sc = null; 
    try { 
     sc = javax.net.ssl.SSLContext.getInstance("SSL"); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 
    try { 
     sc.init(null, trustAllCerts, null); 
    } catch (KeyManagementException e) { 
     e.printStackTrace(); 
    } 
    javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 
} 
class miTM implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager{ 

    public java.security.cert.X509Certificate[] getAcceptedIssuers(){ 
     return null; 
    } 

    public boolean isServerTrusted(java.security.cert.X509Certificate[] certs){ 
     return true; 
     } 

    public boolean isClientTrusted(java.security.cert.X509Certificate[] certs){ 
     return true; 
    } 

    public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException{ 
     return; 
    } 

    public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException{ 
     return; 
     } 
} 
इस कोड के साथ

, मैं ठीक निम्नलिखित प्रदर्शन कर सकते हैं:

URL url = new URL(urlString); 
URLConnection cnx = url.openConnection(); 
cnx.connect(); 

InputStream ins = cnx.getInputStream(); 
BufferedReader in = new BufferedReader(new InputStreamReader(ins)); 
String curline; 
while((curline = in.readLine()) != null) { 
    System.out.println(curline); 
} 

हालांकि, मैं ऐसा नहीं कर सकते निम्नलिखित:

httpClient = new HttpClient(); 
PostMethod postMethod = null; 
int intResult = 0; 
postMethod = new PostMethod(authURL); 
Enumeration emParams = authParams.propertyNames(); 
while (emParams.hasMoreElements()) { 
    String paramName = (String) emParams.nextElement(); 
    String paramValue = authParams.getProperty(paramName); 
    postMethod.addParameter(paramName, paramValue); 
} 

intResult = httpClient.executeMethod(postMethod); 
postMethod.releaseConnection(); 
ins.close(); 

जब executeMethod (postMethod) निष्पादित किया गया है, मुझे एक SSLHandshakeException, CertPathBuilderException, और इसी तरह मिलता है।

इसका समाधान करने के लिए मैं क्या कर सकता हूं? मैं या तो प्रमाण पत्र स्वीकार करने या बस सभी प्रमाण पत्र सत्यापन को छोड़ने के बारे में सोच रहा हूं (क्योंकि कार्यक्रम आंतरिक नेटवर्क के भीतर आंतरिक रूप से चलता है)। अपनी खुद की SecureProtocolSocketFactory रूप Apache HttpClient 3 SSL guide में विस्तार से बताया

धन्यवाद

+0

आप अपाचे HttpClient 3.x उपयोग कर रहे हैं (या 4)? – Bruno

उत्तर

5

ऐसा लगता है कि अपाचे HttpClient 3. उपयोग कर रहे हैं यह वास्तव में 3 संस्करण है, तो आप का निर्माण करने की आवश्यकता है। एक example here है।

अपाचे HttpClient 4 के लिए, आप एक SSLContextthe answers to this question में वर्णित के रूप (होस्ट नाम सत्यापन के बारे में नोट सहित), (HttpClient) SSLSocketFactory के निर्माता को पारित करने के लिए सक्षम होना चाहिए।

हालांकि, आम तौर पर बोलते हुए, इस दृष्टिकोण का पालन न करें। आप एसएसएल/टीएलएस कनेक्शन के प्रमाणीकरण हिस्से को प्रभावी ढंग से अक्षम कर रहे हैं, जिससे एमआईटीएम हमलों के लिए यह कमजोर हो जाता है।

आपको this answer में वर्णित अनुसार, आपको अपने ग्राहक के ट्रस्ट स्टोर में सर्वर प्रमाण पत्र स्पष्ट रूप से आयात करना चाहिए।

मैं सोच रहा हूँ या तो प्रमाण पत्र को स्वीकार करने या सिर्फ सभी प्रमाणपत्र सत्यापन को दरकिनार (के रूप में कार्यक्रम के एक निजी नेटवर्क में आंतरिक रूप से चलता है)।

आप क्या कह रहे हैं कि आप केवल अपने निजी नेटवर्क में एन्क्रिप्शन के लिए एसएसएल/टीएलएस का उपयोग करने के इच्छुक हैं क्योंकि आप अपने उपयोगकर्ताओं पर भरोसा नहीं करते हैं कि वे अपनी मशीनों के आसपास यातायात को न देख सकें , लेकिन आप यह भी मान रहे हैं कि ये उपयोगकर्ता एमआईटीएम हमले करने में सक्षम नहीं होंगे। यह काफी समझ में नहीं आता है। यदि आप उन पर भरोसा करते हैं, तो आप डेटा को स्पष्ट रूप से भी भेज सकते हैं। यदि आप नहीं करते हैं, तो आपको प्रमाणीकरण चरणों (प्रमाण पत्र और होस्ट नाम सत्यापन) सहित SSL/TLS को ठीक से लागू करना चाहिए।

+0

धन्यवाद! मैं अपाचे एचटीपी क्लाइंट 3.x का उपयोग कर रहा था, लेकिन 4 के साथ जाने का फैसला किया। मैंने आपकी सिफारिश का पालन किया और यह काम किया। एक बार फिर धन्यवाद। – ms1013

1

HttpClient 4.3:

 HttpClientBuilder cb = HttpClientBuilder.create(); 
    SSLContextBuilder sslcb = new SSLContextBuilder(); 
    sslcb.loadTrustMaterial(KeyStore.getInstance(KeyStore.getDefaultType()), new TrustSelfSignedStrategy()); 
    cb.setSslcontext(sslcb.build()); 
    CloseableHttpClient httpclient = cb.build(); 
+0

क्या आप इसे थोड़ा सा समझा सकते हैं? – benka