2010-06-28 19 views
17

मैं https://someUrl.com/somePath से कनेक्ट करने के लिए एंड्रॉइड पर एचटीपी क्लाइंट का उपयोग कर रहा हूं। समस्या यह है कि साइट का प्रमाणपत्र * .someUrl.com के लिए है, someUrl.com नहीं, इसलिए मुझे एक एसएसएलएक्सप्शन मिलता है। साइट के हिस्से पर लंगड़ा, हाँ, लेकिन जब तक कि मैं इसे ठीक नहीं कर पाता, मैं अटक गया हूं। क्या कोई तरीका है कि मैं HttpClient को प्रमाणित करने और प्रमाण पत्र स्वीकार करने के लिए प्राप्त कर सकता हूं?एंड्रॉइड एचटीपी क्लाइंट - सर्टिफिकेट में होस्टनाम <example.com> से मेल नहीं खाता! = <*। Example.com>

उत्तर

33

यह मेरा (संपादित) समाधान:

class MyVerifier extends AbstractVerifier { 

    private final X509HostnameVerifier delegate; 

    public MyVerifier(final X509HostnameVerifier delegate) { 
     this.delegate = delegate; 
    } 

    @Override 
    public void verify(String host, String[] cns, String[] subjectAlts) 
       throws SSLException { 
     boolean ok = false; 
     try { 
      delegate.verify(host, cns, subjectAlts); 
     } catch (SSLException e) { 
      for (String cn : cns) { 
       if (cn.startsWith("*.")) { 
        try { 
          delegate.verify(host, new String[] { 
           cn.substring(2) }, subjectAlts); 
          ok = true; 
        } catch (Exception e1) { } 
       } 
      } 
      if(!ok) throw e; 
     } 
    } 
} 


public DefaultHttpClient getTolerantClient() { 
    DefaultHttpClient client = new DefaultHttpClient(); 
    SSLSocketFactory sslSocketFactory = (SSLSocketFactory) client 
      .getConnectionManager().getSchemeRegistry().getScheme("https") 
      .getSocketFactory(); 
    final X509HostnameVerifier delegate = sslSocketFactory.getHostnameVerifier(); 
    if(!(delegate instanceof MyVerifier)) { 
     sslSocketFactory.setHostnameVerifier(new MyVerifier(delegate)); 
    } 
    return client; 
} 

यह डिफ़ॉल्ट व्यवहार में बदलाव नहीं जब तक वहाँ एक वाइल्डकार्ड डोमेन है का लाभ दिया है, और कहा कि मामले में यह पुन: वैधताएं जैसे कि 2 भाग डोमेन (उदाहरण के लिए, someUrl.com) प्रमाण पत्र का हिस्सा थे, अन्यथा मूल अपवाद को पुनर्स्थापित किया जाता है। इसका मतलब है कि वास्तव में अमान्य कर्ट अभी भी असफल हो जाएंगे।

+0

मैंने उपर्युक्त का उपयोग करने की कोशिश की, लेकिन कभी-कभी स्टैक ओवरफ़्लो अपवाद प्राप्त होते हैं - सत्यापित() विधि कभी भी रिकर्सिंग को रोक नहीं देती है। कुछ सौ हजार इंस्टॉलों में से, यह सप्ताह में लगभग 80 बार होता है। क्या आपने इसके साथ कोई समस्या देखी है? – user291701

+0

@ user291701 मैंने आपकी समस्या के चारों ओर प्रयास करने और काम करने के लिए कोड संपादित किया है। मुझे लगता है कि समस्या यह है कि आप एक ही कारखाने पर फिर से सत्यापनकर्ता को सेट अप करते हैं, इसलिए यह किसी भी तरह से खुद को प्रस्तुत करने के लिए समाप्त होता है ... यदि आपको बेहतर तरीका मिल जाता है तो मेरे उत्तर को संपादित करने के लिए स्वतंत्र महसूस करें। – noah

+0

किसी भी मामले में, मुझे सामना करना पड़ रहा है 'सर्वर अनुरोध की सेवा नहीं कर सकता क्योंकि मीडिया प्रकार असमर्थित है' त्रुटि। इसके कारण के बारे में कोई सुराग नहीं है। –

1

यदि यह *.someUrl.com चाहता है, तो ऐसा लगता है कि आप इसे के बजाय www.someUrl.com/somePath दे सकते हैं।

+1

नहीं की अनदेखी करने के कहते हैं। www.someUrl.com कुछ यूआरएल.एम. – noah

+0

पर रीडायरेक्ट करता है मुझे लगता है कि यह बेकार है, फिर। क्या आपको वास्तव में https की आवश्यकता है? मुझे ऐसा लगता है, लेकिन इससे जीवन बहुत आसान हो जाएगा। –

+0

यह साइट एक महान अस्थायी समाधान है जब साइट रीडायरेक्ट नहीं करती है! –

3

एंड्रॉइड पर बाउंसीकास्टल बहुत पुराना है और यह वाइल्डकार्ड प्रमाण पत्र को मान्यता नहीं देता है।

वाइल्डकार्ड की जांच के लिए आप अपना खुद का X509TrustManager लिख सकते हैं।

या यदि आप जोखिम स्वीकार कर सकते हैं तो आप सर्टिफिकेट चेक को पूरी तरह अक्षम कर सकते हैं। , इस सवाल देखें

Self-signed SSL acceptance on Android

+0

असल में जेडजेड, यदि ओपी साइट के नाम और प्रमाण पत्र की संरचना के बारे में सही है, तो त्रुटि संदेश सही है: **। SomeUrl.com * www.someUrl.com और something.someUrl से मेल खाना चाहिए। कॉम, लेकिन * नहीं * someUrl.com या this.that.someUrl.com। –

1

यदि आप एक WebView का उपयोग सिर्फ

webview.clearSslPreferences(); 

SSL त्रुटियाँ

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