2016-09-01 10 views
7

ऐसे तीन होस्ट हैं जो एंड्रॉइड ऐप प्रमाणीकरण और प्रमाणीकरण करते हैं। अंतिम होस्ट आरईएसटी एपीआई है। ओथ प्रमाणीकरण और प्राधिकरण प्रक्रिया का उपयोग करने के लिए पहली बार यह बिना किसी समस्या के काम करता है।एंड्रॉइड java.security.cert.CertPathValidatorException: प्रमाणीकरण पथ के लिए ट्रस्ट एंकर

लेकिन उपयोगकर्ता लॉगिन के बाद ऐप को मारता है और आरईएसटी एपीआई द्वारा प्रदान की जाने वाली सेवाओं तक पहुंचता है और फिर ऐप खोलता है, तो यह समस्या उत्पन्न होती है। इस समय प्रमाणीकरण और प्रमाणीकरण प्रक्रिया नहीं हो रही है, केवल आरईएसटी एपीआई। यह java.security.cert.CertPathValidatorExceptionके कारण हुआ लेकिन यह पहले उपयोग के दौरान काम कर रहा था (लॉगिन करें और फिर ऐप का उपयोग करें)।

क्या कोई इस अपवाद के पीछे परिदृश्य और ऐप के साथ क्या गलत बता सकता है। यह काम करता है अगर प्रमाणीकरण अपवादों को this SO answer के अनुसार बोले के रूप में अनदेखा किया जाता है।

SSLSocketFactory sslSocketFactory = null; 

     try { 
      TrustManagerFactory tmf = TrustManagerFactory.getInstance(
        TrustManagerFactory.getDefaultAlgorithm()); 
      // Initialise the TMF as you normally would, for example: 
      try { 
       tmf.init((KeyStore)null); 
      } catch(KeyStoreException e) { 
       e.printStackTrace(); 
      } 
      TrustManager[] trustManagers = tmf.getTrustManagers(); 

      final X509TrustManager origTrustmanager = (X509TrustManager)trustManagers[0]; 

      // Create a trust manager that does not validate certificate chains 
      TrustManager[] wrappedTrustManagers = new TrustManager[]{ 
        new X509TrustManager() { 
         public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
          return origTrustmanager.getAcceptedIssuers(); 
         } 

         public void checkClientTrusted(X509Certificate[] certs, String authType) { 
          try { 
           origTrustmanager.checkClientTrusted(certs, authType); 
          } catch(CertificateException e) { 
           e.printStackTrace(); 
          } 
         } 

         public void checkServerTrusted(X509Certificate[] certs, String authType) { 
          try { 
           origTrustmanager.checkServerTrusted(certs, authType); 
          } catch(CertificateException e) { 
           e.printStackTrace(); 
          } 
         } 
        } 
      }; 
      //TrustManager[] trustAllCerts = TrustManagerFactory.getInstance("SSL").getTrustManagers(); 

      // Install the all-trusting trust manager 
      final SSLContext sslContext = SSLContext.getInstance("TLS"); 
      sslContext.init(null, wrappedTrustManagers, new java.security.SecureRandom()); 
      // Create an ssl socket factory with our all-trusting manager 
      sslSocketFactory = sslContext.getSocketFactory(); 
     } catch (NoSuchAlgorithmException | KeyManagementException e) { 
      e.printStackTrace(); 
     } 
     return sslSocketFactory; 

मैं http अनुरोधों के लिए Okhttp 3 का उपयोग कर रहा हूं। कोई भी सुझाव इस मुद्दे को हल करने में मदद करेगा। और अगर मैं उपरोक्त कोड स्निपेट का उपयोग करता हूं, तो कृपया मुझे बताएं, क्या यह एक सुरक्षा उल्लंघन है? क्या यह ऐप की सुरक्षा पर असर पड़ेगा?

+0

नोट: आपके 'चेकसेवर ट्रस्टेड' कार्यान्वयन बेकार है क्योंकि आप प्रमाणपत्र अपवाद को पकड़ते हैं और अनदेखा करते हैं। इसलिए सभी सर्वर प्रमाणपत्र (भरोसेमंद और अविश्वसनीय) स्वीकार किए जाते हैं! स्पष्टीकरण के लिए – Robert

+0

@Robert धन्यवाद। हां ** सुरक्षा परिप्रेक्ष्य में यह असुरक्षित और बेकार है **, मुझे अपने उत्तर में वर्णित सही समाधान मिला है। –

उत्तर

12

मैं दूसरों के लाभ के लिए एंड्रॉइड डेवलपर साइट के अनुसार परिदृश्य और समाधान के बारे में एक विचार देने के लिए इसका उत्तर दे रहा हूं। मैंने इसे कस्टम ट्रस्ट मैनेजर का उपयोग करके हल किया है।

समस्या सर्वर प्रमाण पत्र के साथ थी, यह मध्यवर्ती प्रमाणपत्र प्राधिकरण को याद करता है। हालांकि पहले प्रवाह प्रमाण पत्र पथ किसी भी तरह से पूरा हो गया है और परिणाम सफल प्रमाणपत्र पथ सत्यापन था।

android developer site में इसके लिए एक समाधान है। यह कस्टम ट्रस्ट मैनेजर का उपयोग करने का सुझाव देता है जो इस सर्वर प्रमाणपत्र पर भरोसा करता है या यह सर्वर श्रृंखला में इंटरमीडिएट सीए को शामिल करने के लिए सर्वर को सुझाव देता है।

कस्टम ट्रस्ट मैनेजर। स्रोत: https://developer.android.com/training/articles/security-ssl.html#UnknownCa

// Load CAs from an InputStream 
// (could be from a resource or ByteArrayInputStream or ...) 
CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
// From https://www.washington.edu/itconnect/security/ca/load-der.crt 
InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt")); 
Certificate ca; 
try { 
    ca = cf.generateCertificate(caInput); 
    System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); 
} finally { 
    caInput.close(); 
} 

// Create a KeyStore containing our trusted CAs 
String keyStoreType = KeyStore.getDefaultType(); 
KeyStore keyStore = KeyStore.getInstance(keyStoreType); 
keyStore.load(null, null); 
keyStore.setCertificateEntry("ca", ca); 

// Create a TrustManager that trusts the CAs in our KeyStore 
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
tmf.init(keyStore); 

// Create an SSLContext that uses our TrustManager 
SSLContext context = SSLContext.getInstance("TLS"); 
context.init(null, tmf.getTrustManagers(), null); 
// Tell the okhttp to use a SocketFactory from our SSLContext 
OkHttpClient okHttpClient client = new OkHttpClient.Builder().sslSocketFactory(context.getSocketFactory()).build(); 

अद्यतन: मेरे समस्या के बाद मध्यवर्ती प्रमाणपत्र प्राधिकार सर्वर साइड से प्रमाणपत्र श्रृंखला में जोड़ा हल किया गया था। यह सबसे अच्छा समाधान है, ऐप के साथ सर्टिफिकेट को बंडल करने के लिए सर्टिफिकेट की समाप्ति या प्रमाण पत्र प्रबंधन से संबंधित किसी भी अन्य मुद्दे पर ऐप को अपडेट करने की आवश्यकता है।

अद्यतन: 03/09/2017 मुझे मिली प्रमाणपत्र फ़ाइल लोड करने का सबसे आसान तरीका कच्चे संसाधन का उपयोग है।

InputStream caInput = new BufferedInputStream(context 
       .getResources().openRawResource(R.raw.certfilename)); 

जहां certfilename संसाधन/कच्चे फ़ोल्डर में प्रमाणपत्र फ़ाइल है। Okhttp के sslSocketFactory(SSLSocketFactory sslSocketFactory) को बहिष्कृत किया गया है और okhttp api doc में सुझाए गए दृष्टिकोण का उपयोग किया जा सकता है।

सर्वर से प्रमाणपत्र प्राप्त करते समय भी openssl का उपयोग करना बेहतर होता है।

openssl s_client -connect {server-address}:{port} -showcerts 

क्योंकि मैं इसे फ़ायरफ़ॉक्स से पकड़ता था और स्थिति का सामना करता था जहां इसे वायरस गार्ड द्वारा बदला गया था।

1

यह समस्या तब भी दिखाई दे सकती है जब फ़ोन की दिनांक/समय सेटिंग सिंक हो जाती है। जब मैं इस मुद्दे का सामना कर रहा था तो मैं एंड्रॉइड डिवाइस पर परीक्षण कर रहा था।

& दिनांक को बहाल करने के लिए वर्तमान मूल्यों के लिए इस मुद्दे को हल किया गया।

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