Android SSL कनेक्शन के लिए ट्रस्ट एंकर नहीं मिला


185

मैं एक IIS6 बॉक्स से कनेक्ट करने का प्रयास कर रहा हूं जो एक godaddy 256bit SSL सर्टिफिकेट चला रहा है, और मुझे यह त्रुटि मिल रही है:

java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

यह निर्धारित करने की कोशिश कर रहा है कि क्या कारण हो सकते हैं, लेकिन अभी रिक्त स्थान आरेखित करें।

यहां बताया गया है कि मैं कैसे कनेक्ट कर रहा हूं:

HttpsURLConnection conn;              
conn = (HttpsURLConnection) (new URL(mURL)).openConnection();
conn.setConnectTimeout(20000);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
String tempString = toString(conn.getInputStream()); 

जवाबों:


78

@ क्रिसपीक्स का घोल खतरनाक है! सभी प्रमाणपत्रों पर भरोसा करना किसी को भी मध्य हमले में एक आदमी को करने की अनुमति देता है! बस ग्राहक को कोई भी प्रमाण पत्र भेजें और वह इसे स्वीकार करेगा!

इस पोस्ट में वर्णित कस्टम ट्रस्ट मैनेजर की तरह अपने प्रमाण पत्र को जोड़ें: HTTPS पर HttpClient का उपयोग करके सभी प्रमाणपत्रों पर भरोसा करना

यद्यपि यह कस्टम प्रमाणपत्र के साथ सुरक्षित कनेक्शन स्थापित करने के लिए थोड़ा अधिक जटिल है, यह आपको मध्य हमले में आदमी के खतरे के बिना वांछित ssl एन्क्रिप्शन सुरक्षा लाएगा!


1
यह स्व-जनित प्रमाणपत्र के साथ काम करने के लिए ठीक है, लेकिन एक (ओपी की तरह) जिसके पास रूट सीए के लिए एक वैध श्रृंखला है, यह बुरी तरह से कॉन्फ़िगर किए गए सर्वर के लिए सिर्फ एक समाधान है - मेरा जवाब देखें।
स्टीव

4
@Stevie हर प्रमाणपत्र स्वीकार करना केवल अवधारणा परीक्षण के प्रमाण के लिए एक विकल्प है, जहां SSL कनेक्शन वह हिस्सा नहीं है जिसे आप परीक्षण करना चाहते हैं। अन्यथा आपको SSL का उपयोग करने की आवश्यकता नहीं है, यदि आप हर प्रमाण पत्र को स्वीकार करते हैं, क्योंकि कनेक्शन सुरक्षित नहीं है!
मथायस बी

1
आह, मुझे क्षमा करें, मुझे लगता है कि एक गलतफहमी है - मैं पूरी तरह से सहमत हूं कि किसी को भी कभी भी हर प्रमाणपत्र को स्वीकार नहीं करना चाहिए! :) मेरी टिप्पणी आपके दूसरे पैराग्राफ के संबंध में थी - एक कस्टम ट्रस्ट मैनेजर का उपयोग करने का सुझाव - जो IMHO एक अनुशंसित समाधान के बजाय एक अंतिम उपाय समाधान होना चाहिए।
स्टेवी

2
जट एक सिर ऊपर .. मैंने 'समाधान' को एक काम के रूप में चिपकाया, जो अधिक मुद्दों का कारण नहीं था, क्योंकि लोगों ने इसे 'अस्थायी काम' के रूप में नहीं देखा था।
क्रिसपिक्स

7
@ क्रिसपिक्स, आपको आंशिक फिक्स नहीं निकालना चाहिए था, यह सिर्फ परीक्षण उद्देश्यों के लिए अच्छा है
ह्यूगो अल्लेक्सिस कार्डोना

224

स्वीकृत उत्तर के विपरीत आपको कस्टम ट्रस्ट मैनेजर की आवश्यकता नहीं है, आपको अपने सर्वर कॉन्फ़िगरेशन को ठीक करने की आवश्यकता है!

गलत तरीके से स्थापित डायनाडॉट / अल्फ़ाज़ल प्रमाणपत्र के साथ अपाचे सर्वर से कनेक्ट करते समय मैंने उसी समस्या को मारा। मैं HttpsUrlConnection (Java / Android) का उपयोग कर कनेक्ट कर रहा हूं, जो फेंक रहा था -

javax.net.ssl.SSLHandshakeException: 
  java.security.cert.CertPathValidatorException: 
    Trust anchor for certification path not found.

वास्तविक समस्या एक सर्वर मिसकंफिगरेशन है - इसे http://www.digicert.com/help/ या इसी तरह की जांच करें और यह आपको समाधान भी बताएगा:

"प्रमाण पत्र एक विश्वसनीय प्राधिकारी (मोज़िला के रूट स्टोर के खिलाफ जाँच) द्वारा हस्ताक्षरित नहीं है। यदि आपने एक विश्वसनीय प्राधिकारी से प्रमाण पत्र खरीदा है, तो आपको संभवतः एक या एक से अधिक मध्यवर्ती प्रमाण पत्र स्थापित करने की आवश्यकता है । अपने प्रमाणपत्र प्रदाता से संपर्क करें। सर्वर प्लेटफ़ॉर्म। "

आप सर्टिफिकेट को ओपनसेल के साथ भी देख सकते हैं:

openssl s_client -debug -connect www.thedomaintocheck.com:443

आप शायद देखेंगे:

Verify return code: 21 (unable to verify the first certificate)

और, आउटपुट में पहले:

depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=21:unable to verify the first certificate`

प्रमाणपत्र श्रृंखला में केवल 1 तत्व (आपका प्रमाणपत्र) होगा:

Certificate chain
 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
  i:/O=AlphaSSL/CN=AlphaSSL CA - G2

... लेकिन हस्ताक्षर करने वाले अधिकारियों को एक श्रृंखला में वापस संदर्भ देना चाहिए जो कि Android (Verisign, GlobalSign, आदि) द्वारा विश्वसनीय है:

Certificate chain
 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
   i:/O=AlphaSSL/CN=AlphaSSL CA - G2
 1 s:/O=AlphaSSL/CN=AlphaSSL CA - G2
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
 2 s:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA

आपके सर्वर को कॉन्फ़िगर करने के लिए निर्देश (और मध्यवर्ती प्रमाण पत्र) आमतौर पर प्राधिकरण द्वारा प्रदान किए जाते हैं जो आपके प्रमाण पत्र को जारी करते हैं, उदाहरण के लिए: http://www.alphassl.com/support/install-root-certificate.html

अपने प्रमाणपत्र जारीकर्ता द्वारा प्रदान किए गए मध्यवर्ती प्रमाणपत्रों को स्थापित करने के बाद अब मुझे HttpsUrlConnection का उपयोग करते समय कोई त्रुटि नहीं है।


3
यदि ओपी के पास सर्वर एसएसएल कॉन्फ़िगरेशन है, जिससे वह जुड़ रहा है, तो यह एक समाधान हो सकता है। लेकिन अगर वह उस सेवा को होस्ट नहीं कर रहा है जिसे वह कनेक्ट कर रहा है तो उसे अपनी तरफ से समस्या को ठीक करना होगा, जिसका अर्थ है कस्टम ट्रस्ट मैनेजर को लागू करना।
मथायस बी

9
आपका समाधान काम करता है, कोई सवाल नहीं, लेकिन क्या आप इस बात से सहमत नहीं हैं कि यह मूल कारण के लिए एक समाधान के बजाय एक समाधान है? अगर मुझे 3 क्लाइंट (एंड्रॉइड, आईओएस, विंडोज मोबाइल) से एक सर्वर से कनेक्ट करना है तो मुझे सभी 3 पर वर्कअराउंड लागू करना होगा, जबकि मैं सर्वर को एक बार ठीक कर सकता हूं और वे सभी "बस काम" करेंगे।
स्टेवी

2
धन्यवाद स्टीवी, मेरे पास 3 महीने के लिए मेरा सर्वर गलत था, और केवल अब मुझे यह पता चला! अब मेरा एंड्रॉइड ऐप
बजे

2
@Stevie मैं अलग-अलग एपीआई के लिए कई कॉल करता हूं जो एक ही डोमेन को साझा करते हैं, लेकिन उनमें से केवल एक के साथ विफल रहता है (javax.net.ssl.SSLHandshakeException) ... किसी भी विचार है कि ऐसा क्यों होगा? और वैसे भी एसएसएल सर्टिफिकेट पर भरोसा नहीं किया जाता है। इसलिए, मैंने सोचा कि सभी कॉल एक ही अपवाद के साथ विफल होनी चाहिए।
एक निष्पक्ष खिलाड़ी

1
@dvaey जो भी सर्वर का मालिक है, उससे संपर्क करें और उन्हें बताएं कि उनका कॉन्‍फ़िगर टूट गया है और उनका https ठीक से काम नहीं कर रहा है - उन्हें यह लिंक देने के लिए इसे digicert.com/help साबित करें ... मुझे लगता है कि वे प्रशंसनीय और त्वरित होंगे संकल्प। अन्यथा आपको अन्य उत्तरों में से एक समाधान कदम उठाना होगा, लेकिन तब आपको या तो कोई सुरक्षा स्वीकार नहीं करनी होगी (सीरियलों को अनदेखा करें) या जब सर्टिफिकेट समाप्त हो जाए और आपके कस्टम ट्रस्ट स्टोर अब नए से मेल न खाएं प्रमाणपत्र।
स्टीवी

17

आप रनटाइम के समय किसी विशेष प्रमाणपत्र पर भरोसा कर सकते हैं।
बस इसे सर्वर से डाउनलोड करें, संपत्तियों में डालें और ssl-utils-android का उपयोग करके इस तरह लोड करें :

OkHttpClient client = new OkHttpClient();
SSLContext sslContext = SslUtils.getSslContextForCertificateFile(context, "BPClass2RootCA-sha2.cer");
client.setSslSocketFactory(sslContext.getSocketFactory());

ऊपर दिए गए उदाहरण में मैंने उपयोग किया है OkHttpClientलेकिन SSLContextजावा में किसी भी क्लाइंट के साथ उपयोग किया जा सकता है।

यदि आपका कोई प्रश्न है, तो कृपया पूछिए। मैं इस छोटी सी लाइब्रेरी का लेखक हूं।


.pfx के बारे में क्या?
चोलत्स्की

2
क्या यह असुरक्षित नहीं है क्योंकि किसी भी उपयोगकर्ता के पास एपीके होने के बाद एक ऐप के लिए संपत्ति फ़ोल्डर तक पहुंच सकता है?
पैट्रिस आंदाला

1
@PatriceAndala, रूट CA सार्वजनिक रूप से उपलब्ध हैं, तो ठीक है
BekaBot

17

नवीनतम Android प्रलेखन (मार्च 2017) पर आधारित अपडेट:

जब आपको इस प्रकार की त्रुटि मिलती है:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374)
        at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209)
        at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478)
        at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433)
        at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
        at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
        at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
        at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
        at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)

समस्या निम्न में से एक हो सकती है:

  1. सर्वर प्रमाणपत्र जारी करने वाला CA अज्ञात था
  2. सर्वर प्रमाणपत्र पर CA द्वारा हस्ताक्षर नहीं किया गया था, लेकिन स्वयं हस्ताक्षरित था
  3. सर्वर कॉन्फ़िगरेशन एक मध्यवर्ती CA गुम है

समाधान HttpsURLConnectionसीए के एक विशिष्ट सेट पर भरोसा करना सिखाना है। कैसे? कृपया https://developer.android.com/training/articles/security-ssl.html#CommonProblems की जांच करें

अन्य जो लाइब्रेरी AsyncHTTPClientसे उपयोग कर रहे हैं com.loopj.android:android-async-http, कृपया HTTPS का उपयोग करने के लिए सेटअप AsyncHttpClient की जाँच करें


5
क्या होगा अगर कोई एक okhttp क्लाइंट का उपयोग कर रहा है?
19

Okhttp के लिए, pls @ mklimek के उत्तर की जांच करें।
user1506104

14

यदि आप रेट्रोफिट का उपयोग करते हैं, तो आपको अपने OkHttpClient को कस्टमाइज़ करना होगा।

retrofit = new Retrofit.Builder()
                        .baseUrl(ApplicationData.FINAL_URL)
                        .client(getUnsafeOkHttpClient().build())
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();

पूर्ण कोड नीचे हैं।

    public class RestAdapter {

    private static Retrofit retrofit = null;
    private static ApiInterface apiInterface;

    public static OkHttpClient.Builder getUnsafeOkHttpClient() {
        try {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[]{};
                        }
                    }
            };

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            return builder;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static ApiInterface getApiClient() {
        if (apiInterface == null) {

            try {
                retrofit = new Retrofit.Builder()
                        .baseUrl(ApplicationData.FINAL_URL)
                        .client(getUnsafeOkHttpClient().build())
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();

            } catch (Exception e) {

                e.printStackTrace();
            }


            apiInterface = retrofit.create(ApiInterface.class);
        }
        return apiInterface;
    }

}

1
मैं कोड का उपयोग करने का प्रयास कर रहा हूं, लेकिन मुझे निम्नलिखित त्रुटि फिर से मिल रही है .. "javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: विश्वास पथ प्रमाण पत्र के लिए लंगर नहीं मिला।" u इसमें मदद कर सकते हैं
विश्व प्रताप

यह कट्टरपंथी असुरक्षित है। प्रयोग नहीं करें।
लोर्ने

धन्यवाद! कोटलिन में विधि getUnsafeOkHttpClient()को फिर से लिखें: stackoverflow.com/a/60507560/2914140
कूलमाइंड

11

बहुत पुरानी पोस्ट का जवाब। लेकिन शायद यह कुछ नौसिखिया की मदद करेगा और यदि उपरोक्त में से गैर काम करता है।

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

समाधान: निम्न समाधान मानता है कि आपके पास निम्न स्थितियाँ हैं

  1. अपने स्थानीय मशीन से दूरस्थ एपीआई तक पहुँचने की कोशिश कर रहा है।
  2. आप Android ऐप के लिए निर्माण कर रहे हैं
  3. आपका दूरस्थ सर्वर प्रॉक्सी निस्पंदन के अंतर्गत है (आप दूरस्थ एपीआई सेवा का उपयोग करने के लिए अपने ब्राउज़र सेटिंग में प्रॉक्सी का उपयोग करते हैं, आमतौर पर मंचन या देव सर्वर)
  4. आप असली डिवाइस पर परीक्षण कर रहे हैं

कदम:

अपने ऐप को साइनअप करने के लिए आपको .Stystore एक्सटेंशन फ़ाइल की आवश्यकता होती है। यदि आप नहीं जानते कि कैसे .keystore फ़ाइल बनाएँ; फिर निम्न अनुभाग के साथ पालन करें। .Stystore फ़ाइल बनाएं अन्यथा अगले भाग पर जाएं Apk फ़ाइल साइन करें

.Stystore फ़ाइल बनाएँ

Android Studio खोलें। शीर्ष मेनू बनाएँ> हस्ताक्षरित उत्पन्न करें पर क्लिक करें। अगली विंडो में Create new ... बटन पर क्लिक करें। नई विंडो में, कृपया सभी क्षेत्रों में डेटा में इनपुट करें। याद रखें कि दो पासवर्ड फ़ील्ड मैं सुझाता हूं कि समान पासवर्ड होना चाहिए; विभिन्न पासवर्ड का उपयोग न करें; और शीर्ष सबसे अधिक फ़ील्ड कुंजी स्टोर पथ पर सहेजें पथ को भी याद रखें :। इनपुट के बाद सभी फ़ील्ड ओके बटन पर क्लिक करें।

Apk फ़ाइल पर हस्ताक्षर करें

अब आपको अपने द्वारा निर्मित .keystore फ़ाइल के साथ एक हस्ताक्षरित ऐप बनाने की आवश्यकता है। इन कदमों का अनुसरण करें

  1. बिल्ड> क्लीन प्रोजेक्ट, सफाई खत्म होने तक प्रतीक्षा करें
  2. बिल्ड> जेनरेट किए गए एपीके
  3. Choose existing...बटन पर क्लिक करें
  4. उस .keystore फ़ाइल का चयन करें जिसे हमने अभी बनाया .keystore फ़ाइल अनुभाग में बनाया है
  5. Create .keystore फाइल सेक्शन में बनाते समय वही पासवर्ड डालें जो आपने बनाया था । फ़ील्ड Key store passwordऔर Key passwordफ़ील्ड के लिए समान पासवर्ड का उपयोग करें । साथ ही उपनाम दर्ज करें
  6. नेक्स्ट बटन पर क्लिक करें
  7. अगली स्क्रीन में; build.gradleफ़ाइलों में आपकी सेटिंग के आधार पर भिन्न हो सकते हैं , आपको चयन करने की आवश्यकता है Build Typesऔर Flavors
  8. के लिए Build Typesचुनें releaseड्रॉप-डाउन से
  9. के लिए Flavorsहालांकि यह होगा में अपनी सेटिंग्स पर निर्भर करता है build.gradleफ़ाइल। stagingइस क्षेत्र से चुनें । मैंने निम्नलिखित सेटिंग्स का build.gradleउपयोग किया है , आप मेरा के समान उपयोग कर सकते हैं, लेकिन सुनिश्चित करें कि आपने applicationIdअपने पैकेज के नाम को बदल दिया है

    productFlavors {
        staging {
            applicationId "com.yourapplication.package"
            manifestPlaceholders = [icon: "@drawable/ic_launcher"]
            buildConfigField "boolean", "CATALYST_DEBUG", "true"
            buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "true"
        }
        production {
            buildConfigField "boolean", "CATALYST_DEBUG", "false"
            buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "false"
        }
    }
  10. नीचे दो Signature Versionsचेकबॉक्स पर क्लिक Finishकरें और बटन पर क्लिक करें।

लगभग वहाँ पहुँच गया:

सारा हार्डवर्क हो गया, अब सच का आंदोलन। प्रॉक्सी द्वारा स्टैगिंग सर्वर का बैकअप लेने के लिए, आपको अपने वास्तविक परीक्षण Android उपकरणों में कुछ सेटिंग करने की आवश्यकता है।

Android डिवाइस में प्रॉक्सी सेटिंग:

  1. एंड्रॉइड फोन के अंदर सेटिंग पर क्लिक करें और फिर वाई-फाई करें
  2. कनेक्टेड वाईफाई पर लॉन्ग प्रेस करें और सेलेक्ट करें Modify network
  3. Advanced optionsयदि आप Proxy Hostnameफ़ील्ड नहीं देख पा रहे हैं तो क्लिक करें
  4. में Proxy Hostnameमेजबान आईपी दर्ज करें या नाम आप कनेक्ट करना चाहते। एक विशिष्ट स्टेजिंग सर्वर को नाम दिया जाएगाstg.api.mygoodcompany.com
  5. पोर्ट के लिए उदाहरण के लिए चार अंकों का पोर्ट नंबर दर्ज करें 9502
  6. Saveबटन मारो

एक अंतिम पड़ाव:

याद रखें कि हमने साइन एपीके फ़ाइल सेक्शन में साइन इन एपीके फ़ाइल जनरेट की है । अब उस एपीके फाइल को इंस्टॉल करने का समय है।

  1. एक टर्मिनल खोलें और हस्ताक्षरित apk फ़ाइल फ़ोल्डर में बदल दिया
  2. अपने Android डिवाइस को अपनी मशीन से कनेक्ट करें
  3. एंड्रॉइड डिवाइस से किसी भी पिछली इंस्टॉल की गई एपीके फाइल को हटा दें
  4. Daud adb install name of the apk file
  5. यदि किसी कारणवश उपरोक्त कमांड वापस आती है adb command not found। के रूप में पूर्ण पथ दर्ज करेंC:\Users\shah\AppData\Local\Android\sdk\platform-tools\adb.exe install name of the apk file

मुझे उम्मीद है कि समस्या हल हो सकती है। अगर नहीं तो कृपया मुझे एक टिप्पणी छोड़ दें।

सलाम!


4

त्रुटि संदेश जो मुझे मिल रहा था वह समान था लेकिन इसका कारण यह था कि स्व हस्ताक्षरित प्रमाणपत्र समाप्त हो गया था। जब Opensl क्लाइंट का प्रयास किया गया था, तो इसने मुझे वह कारण दिया जिसकी अनदेखी की गई थी जब मैं फ़ायरफ़ॉक्स से प्रमाणपत्र संवाद की जाँच कर रहा था।

तो सामान्य तौर पर, यदि किस्टोर और इसके "वैलिड" में प्रमाण पत्र है, तो यह त्रुटि बंद हो जाएगी।


1
यदि प्रमाणपत्र समाप्त हो गया है, तो यह कई मानकों के अनुसार मान्य नहीं है। एक कस्टम TrustManagerका उपयोग करने और मानदंडों के एक अलग सेट का उपयोग करने के लिए इसका ठीक है। लेकिन बॉक्स से बाहर, यही आपके साथ काम करना है।
jww

4

Android क्लाइंट से Kurento सर्वर से कनेक्ट करते समय मुझे यही समस्या थी। Kurento सर्वर jks प्रमाणपत्र का उपयोग करते हैं, इसलिए मुझे इसे pem में बदलना पड़ा। रूपांतरण के लिए इनपुट के रूप में मैंने cert.pem फ़ाइल का उपयोग किया और यह ऐसी त्रुटियों को जन्म देती है। लेकिन अगर उपयोग fullchain.pem बजाय cert.pem - सभी ठीक है।


3

Https://www.ssllabs.com/ssltest/ का उपयोग करेंकिसी डोमेन का परीक्षण करने के लिए का ।

कोटलिन में शिहाब उद्दीन का समाधान ।

import java.security.SecureRandom
import java.security.cert.X509Certificate
import javax.net.ssl.*
import javax.security.cert.CertificateException

companion object {

    private val gson: Gson
    private val retrofit: Retrofit

    init {

        val okHttpClient = getUnsafeOkHttpClient() // OkHttpClient().newBuilder()
            .build()

        gson = GsonBuilder().setLenient().create()

        retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build()
    }

    private fun getUnsafeOkHttpClient(): OkHttpClient.Builder =
        try {
            // Create a trust manager that does not validate certificate chains
            val trustAllCerts: Array<TrustManager> = arrayOf(
                object : X509TrustManager {
                    @Throws(CertificateException::class)
                    override fun checkClientTrusted(chain: Array<X509Certificate?>?,
                                                    authType: String?) = Unit

                    @Throws(CertificateException::class)
                    override fun checkServerTrusted(chain: Array<X509Certificate?>?,
                                                    authType: String?) = Unit

                    override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
                }
            )
            // Install the all-trusting trust manager
            val sslContext: SSLContext = SSLContext.getInstance("SSL")
            sslContext.init(null, trustAllCerts, SecureRandom())
            // Create an ssl socket factory with our all-trusting manager
            val sslSocketFactory: SSLSocketFactory = sslContext.socketFactory
            val builder = OkHttpClient.Builder()
            builder.sslSocketFactory(sslSocketFactory,
                trustAllCerts[0] as X509TrustManager)
            builder.hostnameVerifier { _, _ -> true }
            builder
        } catch (e: Exception) {
            throw RuntimeException(e)
        }
}

2

मुझे वही समस्या थी जो मुझे मिली थी कि प्रमाण पत्र .crt फ़ाइल मैंने प्रदान की थी एक मध्यवर्ती प्रमाणपत्र गायब है। इसलिए मैंने अपने सर्वर व्यवस्थापक से सभी .crt फ़ाइलों को पूछा, फिर उन्हें उल्टे क्रम में छुपा दिया।

पूर्व। 1. Root.crt 2. Inter.crt 3. myCrt.crt

विंडोज़ में मैंने कॉपी की कॉपी Inter.crt + Root.crt newCertificate.crt

(यहां मैंने myCrt.crt की उपेक्षा की)

तब मैंने इनपुटस्ट्रीम के माध्यम से कोड में newCertificate.crt फ़ाइल प्रदान की। काम किया।


हमारा भी यही मुद्दा था। इंटरमीडिएट का प्रमाणपत्र गायब था
निधिन चंद्रन

1

ट्रस्ट एंकर त्रुटि कई कारणों से हो सकती है। मेरे लिए बस इतना ही था कि मैं https://example.com/इसके बजाय पहुँच का प्रयास कर रहा था https://www.example.com/

इसलिए आप अपना खुद का ट्रस्ट मैनेजर बनाने के लिए अपने URL को दोबारा जांचना चाहेंगे (जैसे मैंने किया)।


0

जिंजरब्रेड फोन में, मुझे हमेशा यह त्रुटि मिलती है: Trust Anchor not found for Android SSL Connectionयहां तक ​​कि अगर मैं अपने प्रमाण पत्र पर भरोसा करने के लिए सेटअप करता हूं।

यहाँ मैं उपयोग कोड है (स्काला भाषा में):

object Security {
    private def createCtxSsl(ctx: Context) = {
        val cer = {
            val is = ctx.getAssets.open("mycertificate.crt")
            try
                CertificateFactory.getInstance("X.509").generateCertificate(is)
            finally
                is.close()
        }
        val key = KeyStore.getInstance(KeyStore.getDefaultType)
        key.load(null, null)
        key.setCertificateEntry("ca", cer)

        val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
    tmf.init(key)

        val c = SSLContext.getInstance("TLS")
        c.init(null, tmf.getTrustManagers, null)
        c
    }

    def prepare(url: HttpURLConnection)(implicit ctx: Context) {
        url match {
            case https: HttpsURLConnection 
                val cSsl = ctxSsl match {
                    case None 
                        val res = createCtxSsl(ctx)
                        ctxSsl = Some(res)
                        res
                    case Some(c)  c
                }
                https.setSSLSocketFactory(cSsl.getSocketFactory)
            case _ 
        }
    }

    def noSecurity(url: HttpURLConnection) {
        url match {
            case https: HttpsURLConnection 
                https.setHostnameVerifier(new HostnameVerifier {
                    override def verify(hostname: String, session: SSLSession) = true
                })
            case _ 
        }
    }
}

और यहाँ कनेक्शन कोड है:

def connect(securize: HttpURLConnection  Unit) {
    val conn = url.openConnection().asInstanceOf[HttpURLConnection]
    securize(conn)
    conn.connect();
    ....
}

try {
    connect(Security.prepare)
} catch {
    case ex: SSLHandshakeException /*if ex.getMessage != null && ex.getMessage.contains("Trust anchor for certification path not found")*/ 
        connect(Security.noSecurity)
}

असल में, मैं अपने कस्टम सर्टिफिकेट पर भरोसा करने के लिए तैयार हूं। यदि वह विफल रहता है, तो मैं सुरक्षा अक्षम कर देता हूं। यह सबसे अच्छा विकल्प नहीं है, लेकिन एकमात्र विकल्प जो मुझे पुराने और छोटी गाड़ी के साथ पता है।

यह नमूना कोड, आसानी से जावा में अनुवादित किया जा सकता है।


Android 2.3.x के लिए समाधान यदि किसी को इसकी आवश्यकता है, तो stackoverflow.com/a/46465722/7125370
Newbie009

0

मेरे मामले में यह एंड्रॉइड 8.0 के अपडेट के बाद हो रहा था। स्व-हस्ताक्षरित प्रमाणपत्र एंड्रॉइड पर भरोसा करने के लिए सेट किया गया था हस्ताक्षर एल्गोरिथ्म SHA1withRSA का उपयोग कर रहा था। हस्ताक्षर एल्गोरिथ्म SHA256withRSA का उपयोग कर एक नए प्रमाणपत्र पर स्विच करने से समस्या ठीक हो गई।


0

मुझे पता है कि आपको सभी प्रमाणपत्रों पर भरोसा करने की आवश्यकता नहीं है, लेकिन मेरे मामले में मुझे कुछ डीबगिंग वातावरण के साथ समस्या थी जहां हमारे पास स्व-हस्ताक्षरित प्रमाण पत्र थे और मुझे एक गंदे समाधान की आवश्यकता थी।

मुझे बस इतना करना था कि इसके आरंभ को बदलना होगा sslContext

mySSLContext.init(null, trustAllCerts, null); 

trustAllCertsइस तरह से कहाँ बनाया गया था:

private final TrustManager[] trustAllCerts= new TrustManager[] { new X509TrustManager() {
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return new java.security.cert.X509Certificate[]{};
    }

    public void checkClientTrusted(X509Certificate[] chain,
                                   String authType) throws CertificateException {
    }

    public void checkServerTrusted(X509Certificate[] chain,
                                   String authType) throws CertificateException {
    }
} };

उम्मीद है कि यह काम आएगा।


यही मैं खोजना चाहता था! धन्यवाद
ऑक्साइड

मुझे त्रुटि मिलती है Hostname '192.168.0.16' was not verified। मैं अपने वेबपेज को अपने डिबगर (IIS एक्सप्रेस) के माध्यम से स्थानीय स्तर पर परीक्षण कर रहा हूं। इसे ठीक करने के लिए कोई भी विचार? धन्यवाद :)
सैम

1
यह मौलिक रूप से असुरक्षित है। प्रयोग नहीं करें।
लोर्ने

0

मुझे एक समान समस्या हुई है और मैंने सभी स्रोतों पर भरोसा करने की रणनीति को पूरी तरह से खारिज कर दिया है।

मैं यहां अपना समाधान साझा करता हूं जो कोटलिन में लागू एक आवेदन पर लागू होता है

मैं पहले प्रमाण पत्र और इसकी वैधता के बारे में जानकारी प्राप्त करने के लिए निम्नलिखित वेबसाइट का उपयोग करने की सलाह दूंगा

अगर यह एंड्रॉइड डिफॉल्ट ट्रस्ट स्टोर में 'स्वीकृत इश्यू' के रूप में नहीं दिखाई देता है , हम उस प्रमाण पत्र मिलता है और आवेदन में शामिल एक कस्टम विश्वास दुकान बनाने के लिए करना चाहिए

मेरे मामले में आदर्श समाधान एक उच्च-स्तरीय ट्रस्ट प्रबंधक बनाना था जो कस्टम और एंड्रॉइड डिफ़ॉल्ट ट्रस्ट स्टोर को जोड़ता है

यहाँ वह उस उच्च स्तर के कोड को उजागर करता है जिसका उपयोग वह OkHttpClient को कॉन्फ़िगर करने के लिए करता है जो उसने रेट्रोफ़िट के साथ उपयोग किया था।

override fun onBuildHttpClient(httpClientBuild: OkHttpClient.Builder) {

        val trustManagerWrapper = createX509TrustManagerWrapper(
            arrayOf(
                getCustomX509TrustManager(),
                getDefaultX509TrustManager()
            )
        )

        printX509TrustManagerAcceptedIssuers(trustManagerWrapper)

        val sslSocketFactory = createSocketFactory(trustManagerWrapper)
        httpClientBuild.sslSocketFactory(sslSocketFactory, trustManagerWrapper)

    }

इस तरह, मैं सर्वर के साथ एक स्व-हस्ताक्षरित प्रमाण पत्र के साथ और अन्य सर्वर के साथ एक विश्वसनीय प्रमाणीकरण इकाई द्वारा जारी किए गए प्रमाण पत्र के साथ संवाद कर सकता हूं

यह वह है, मुझे आशा है कि यह किसी की मदद कर सकता है।


0

मुझे पता है कि यह एक बहुत पुराना लेख है, लेकिन मैं इस लेख के दौरान आया जब अपने विश्वास लंगर मुद्दों को हल करने की कोशिश कर रहा था। मैंने पोस्ट किया है कि मैंने इसे कैसे तय किया। यदि आपने अपनी रूट CA को पूर्व-स्थापित किया है तो आपको मेनिफ़ेस्ट में कॉन्फ़िगरेशन जोड़ना होगा।

https://stackoverflow.com/a/60102517/114265


केवल एपीआई 24+ के लिए
बेकाबू

@BekaBot - यह शायद सच है, लेकिन 23 के अनुसार और डिफ़ॉल्ट रूप से ट्रस्ट उपयोगकर्ता सेरेमनी के नीचे, डिफ़ॉल्ट रूप से, सभी ऐप्स के सुरक्षित कनेक्शन (प्रोटोकॉल जैसे TLS और HTTPS का उपयोग करके) पहले से इंस्टॉल किए गए सिस्टम CA पर भरोसा करते हैं, और Android 6.0 को लक्षित करने वाले ऐप्स (एपीआई स्तर 23) और निम्न भी डिफ़ॉल्ट रूप से उपयोगकर्ता द्वारा जोड़े गए सीए स्टोर पर भरोसा करते हैं
जीआर एनवॉय

-1
**Set proper alias name**
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509","BC");
            X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream);
            String alias = cert.getSubjectX500Principal().getName();
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null);
trustStore.setCertificateEntry(alias, cert);

-2

मैंने भी इसी समस्या का सामना किया है। मैं बस http, जैसे hhtps को हटाता हूं

final public static String ROOT_URL = "https://example.com"; सेवा final public static String ROOT_URL = "http://example.com";

फाइनली, मैंने इस समस्या को हल कर दिया।


निश्चित रूप से यह सिर्फ SSL सुरक्षा को समीकरण से हटा रहा है, जो शायद उत्पादन के माहौल के लिए एक बुरा विचार है।
महीने तक Dragonthoughts

यह वास्तव में एक समाधान नहीं है, एसएसएल सुरक्षा हटा रहा है।
omega1
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.