[java] HTTPS पर HttpClient का उपयोग कर सभी प्रमाणपत्रों पर भरोसा करना



8 Answers

Httpclient का उपयोग करके एंड्रॉइड पर "विश्वसनीय नहीं" अपवाद को ठीक करने के लिए आपके पास मूल रूप से चार संभावित समाधान हैं:

  1. सभी प्रमाणपत्रों पर भरोसा करें। ऐसा मत करो, जब तक आप वास्तव में नहीं जानते कि आप क्या कर रहे हैं।
  2. एक कस्टम SSLSocketFactory बनाएं जो केवल आपके प्रमाणपत्र पर भरोसा करता है। यह तब तक काम करता है जब तक आप जानते हैं कि आप किन सर्वरों से कनेक्ट होने जा रहे हैं, लेकिन जैसे ही आपको किसी भिन्न SSL प्रमाणपत्र से नए सर्वर से कनेक्ट करने की आवश्यकता है, आपको अपने ऐप को अपडेट करना होगा।
  3. एक कीस्टोर फ़ाइल बनाएं जिसमें प्रमाणपत्रों की एंड्रॉइड की "मास्टर सूची" है, फिर अपना खुद का जोड़ें। यदि इनमें से कोई भी कर्ट सड़क से समाप्त हो जाता है, तो आप उन्हें अपने ऐप में अपडेट करने के लिए ज़िम्मेदार हैं। मैं ऐसा करने का कोई कारण नहीं सोच सकता।
  4. एक कस्टम SSLSocketFactory बनाएं जो अंतर्निहित प्रमाणपत्र KeyStore का उपयोग करता है, लेकिन डिफ़ॉल्ट के साथ सत्यापित करने में विफल होने वाली किसी भी चीज़ के लिए वैकल्पिक कुंजीस्टोर पर वापस आ जाता है।

यह उत्तर समाधान # 4 का उपयोग करता है, जो मुझे सबसे मजबूत लगता है।

समाधान एक SSLSocketFactory का उपयोग करना है जो एकाधिक कुंजीस्टोर स्वीकार कर सकता है, जिससे आप अपने स्वयं के प्रमाणपत्रों के साथ अपने स्वयं के कीस्टोर की आपूर्ति कर सकते हैं। यह आपको अतिरिक्त शीर्ष-स्तरीय प्रमाणपत्र लोड करने की अनुमति देता है जैसे थॉवे जो कुछ एंड्रॉइड डिवाइसों पर अनुपलब्ध हो सकता है। यह आपको अपने स्वयं के हस्ताक्षरित प्रमाण पत्र भी लोड करने की अनुमति देता है। यह पहले अंतर्निहित डिफ़ॉल्ट डिवाइस प्रमाणपत्र का उपयोग करेगा, और केवल आवश्यकतानुसार आपके अतिरिक्त प्रमाणपत्रों पर वापस आ जाएगा।

सबसे पहले, आप यह निर्धारित करना चाहते हैं कि आप अपने कीस्टोर में कौन सा प्रमाणपत्र खो रहे हैं। निम्न आदेश चलाएं:

openssl s_client -connect www.yourserver.com:443

और आप निम्न की तरह आउटपुट देखेंगे:

Certificate chain
 0 s:/O=www.yourserver.com/OU=Go to 
   https://www.thawte.com/repository/index.html/OU=Thawte SSL123 
   certificate/OU=Domain Validated/CN=www.yourserver.com
   i:/C=US/O=Thawte, Inc./OU=Domain Validated SSL/CN=Thawte DV SSL CA
 1 s:/C=US/O=Thawte, Inc./OU=Domain Validated SSL/CN=Thawte DV SSL CA
   i:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 
   2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA

जैसा कि आप देख सकते हैं, हमारा रूट प्रमाणपत्र Thawte से है। अपने प्रदाता की वेबसाइट पर जाएं और संबंधित प्रमाणपत्र खोजें। हमारे लिए, यह here था, और आप देख सकते हैं कि जिसकी हमें आवश्यकता थी वह एक कॉपीराइट 2006 था।

यदि आप एक स्व-हस्ताक्षरित प्रमाणपत्र का उपयोग कर रहे हैं, तो आपको पिछले चरण को करने की आवश्यकता नहीं है क्योंकि आपके पास पहले से ही आपका हस्ताक्षर प्रमाणपत्र है।

फिर, लापता हस्ताक्षर प्रमाणपत्र वाले एक कीस्टोर फ़ाइल बनाएं। क्रेज़ीबोब के पास एंड्रॉइड पर यह कैसे करना है , लेकिन विचार निम्नलिखित है:

यदि आपके पास पहले से नहीं है, तो उछाल वाली महल प्रदाता लाइब्रेरी से डाउनलोड करें: http://www.bouncycastle.org/latest_releases.html । यह नीचे आपके क्लासपाथ पर जाएगा।

सर्वर से प्रमाण पत्र निकालने और एक पेम फ़ाइल बनाने के लिए एक आदेश चलाएं। इस मामले में, mycert.pem।

echo | openssl s_client -connect ${MY_SERVER}:443 2>&1 | \
 sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > mycert.pem

फिर कुंजीस्टोर बनाने के लिए निम्न आदेश चलाएं।

export CLASSPATH=/path/to/bouncycastle/bcprov-jdk15on-155.jar
CERTSTORE=res/raw/mystore.bks
if [ -a $CERTSTORE ]; then
    rm $CERTSTORE || exit 1
fi
keytool \
      -import \
      -v \
      -trustcacerts \
      -alias 0 \
      -file <(openssl x509 -in mycert.pem) \
      -keystore $CERTSTORE \
      -storetype BKS \
      -provider org.bouncycastle.jce.provider.BouncyCastleProvider \
      -providerpath /path/to/bouncycastle/bcprov-jdk15on-155.jar \
      -storepass some-password

आप देखेंगे कि उपरोक्त स्क्रिप्ट परिणाम res/raw/mystore.bks में परिणाम res/raw/mystore.bks । अब आपके पास एक फ़ाइल है जिसे आप अपने एंड्रॉइड ऐप में लोड करेंगे जो गायब प्रमाणपत्र (ओं) प्रदान करता है।

ऐसा करने के लिए, SSL योजना के लिए अपना SSLSocketFactory पंजीकृत करें:

final SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", createAdditionalCertsSSLSocketFactory(), 443));

// and then however you create your connection manager, I use ThreadSafeClientConnManager
final HttpParams params = new BasicHttpParams();
...
final ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params,schemeRegistry);

अपना SSLSocketFactory बनाने के लिए:

protected org.apache.http.conn.ssl.SSLSocketFactory createAdditionalCertsSSLSocketFactory() {
    try {
        final KeyStore ks = KeyStore.getInstance("BKS");

        // the bks file we generated above
        final InputStream in = context.getResources().openRawResource( R.raw.mystore);  
        try {
            // don't forget to put the password used above in strings.xml/mystore_password
            ks.load(in, context.getString( R.string.mystore_password ).toCharArray());
        } finally {
            in.close();
        }

        return new AdditionalKeyStoresSSLSocketFactory(ks);

    } catch( Exception e ) {
        throw new RuntimeException(e);
    }
}

और आखिरकार, अतिरिक्त KeyStoresSSLSocketFactory कोड, जो आपके नए कीस्टोर को स्वीकार करता है और जांच करता है कि अंतर्निहित कीस्टोर SSL प्रमाणपत्र को सत्यापित करने में विफल रहता है:

/**
 * Allows you to trust certificates from additional KeyStores in addition to
 * the default KeyStore
 */
public class AdditionalKeyStoresSSLSocketFactory extends SSLSocketFactory {
    protected SSLContext sslContext = SSLContext.getInstance("TLS");

    public AdditionalKeyStoresSSLSocketFactory(KeyStore keyStore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
        super(null, null, null, null, null, null);
        sslContext.init(null, new TrustManager[]{new AdditionalKeyStoresTrustManager(keyStore)}, null);
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
        return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
    }

    @Override
    public Socket createSocket() throws IOException {
        return sslContext.getSocketFactory().createSocket();
    }



    /**
     * Based on http://download.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#X509TrustManager
     */
    public static class AdditionalKeyStoresTrustManager implements X509TrustManager {

        protected ArrayList<X509TrustManager> x509TrustManagers = new ArrayList<X509TrustManager>();


        protected AdditionalKeyStoresTrustManager(KeyStore... additionalkeyStores) {
            final ArrayList<TrustManagerFactory> factories = new ArrayList<TrustManagerFactory>();

            try {
                // The default Trustmanager with default keystore
                final TrustManagerFactory original = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                original.init((KeyStore) null);
                factories.add(original);

                for( KeyStore keyStore : additionalkeyStores ) {
                    final TrustManagerFactory additionalCerts = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                    additionalCerts.init(keyStore);
                    factories.add(additionalCerts);
                }

            } catch (Exception e) {
                throw new RuntimeException(e);
            }



            /*
             * Iterate over the returned trustmanagers, and hold on
             * to any that are X509TrustManagers
             */
            for (TrustManagerFactory tmf : factories)
                for( TrustManager tm : tmf.getTrustManagers() )
                    if (tm instanceof X509TrustManager)
                        x509TrustManagers.add( (X509TrustManager)tm );


            if( x509TrustManagers.size()==0 )
                throw new RuntimeException("Couldn't find any X509TrustManagers");

        }

        /*
         * Delegate to the default trust manager.
         */
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            final X509TrustManager defaultX509TrustManager = x509TrustManagers.get(0);
            defaultX509TrustManager.checkClientTrusted(chain, authType);
        }

        /*
         * Loop over the trustmanagers until we find one that accepts our server
         */
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            for( X509TrustManager tm : x509TrustManagers ) {
                try {
                    tm.checkServerTrusted(chain,authType);
                    return;
                } catch( CertificateException e ) {
                    // ignore
                }
            }
            throw new CertificateException();
        }

        public X509Certificate[] getAcceptedIssuers() {
            final ArrayList<X509Certificate> list = new ArrayList<X509Certificate>();
            for( X509TrustManager tm : x509TrustManagers )
                list.addAll(Arrays.asList(tm.getAcceptedIssuers()));
            return list.toArray(new X509Certificate[list.size()]);
        }
    }

}
Question

हाल ही में HttpClient पर एचटीपी HttpClient के बारे में एक प्रश्न पोस्ट किया गया ( यहां पाया गया )। मैंने कुछ रास्ता बनाया है, लेकिन मैंने नए मुद्दों में भाग लिया है। मेरी आखिरी समस्या के साथ, मुझे ऐसा कोई उदाहरण नहीं मिल रहा है जो मेरे लिए काम करता है। असल में, मैं चाहता हूं कि मेरा क्लाइंट किसी प्रमाणपत्र को स्वीकार करे (क्योंकि मैं केवल एक सर्वर को इंगित करता हूं) लेकिन मुझे javax.net.ssl.SSLException: Not trusted server certificate exception. मिल रहा है javax.net.ssl.SSLException: Not trusted server certificate exception.

तो मेरे पास यही है:

public void connect() throws A_WHOLE_BUNCH_OF_EXCEPTIONS {

    HttpPost post = new HttpPost(new URI(PROD_URL));
    post.setEntity(new StringEntity(BODY));

    KeyStore trusted = KeyStore.getInstance("BKS");
    trusted.load(null, "".toCharArray());
    SSLSocketFactory sslf = new SSLSocketFactory(trusted);
    sslf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

    SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme ("https", sslf, 443));
    SingleClientConnManager cm = new SingleClientConnManager(post.getParams(),
            schemeRegistry);

    HttpClient client = new DefaultHttpClient(cm, post.getParams());
    HttpResponse result = client.execute(post);
}

और यहां मुझे जो त्रुटि मिल रही है:

W/System.err(  901): javax.net.ssl.SSLException: Not trusted server certificate 
W/System.err(  901):    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:360) 
W/System.err(  901):    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:92) 
W/System.err(  901):    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:321) 
W/System.err(  901):    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:129) 
W/System.err(  901):    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 
W/System.err(  901):    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 
W/System.err(  901):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:348) 
W/System.err(  901):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 
W/System.err(  901):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 
W/System.err(  901):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 
W/System.err(  901):    at me.harrisonlee.test.ssl.MainActivity.connect(MainActivity.java:129) 
W/System.err(  901):    at me.harrisonlee.test.ssl.MainActivity.access$0(MainActivity.java:77) 
W/System.err(  901):    at me.harrisonlee.test.ssl.MainActivity$2.run(MainActivity.java:49) 
W/System.err(  901): Caused by: java.security.cert.CertificateException: java.security.InvalidAlgorithmParameterException: the trust anchors set is empty 
W/System.err(  901):    at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:157) 
W/System.err(  901):    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:355) 
W/System.err(  901):    ... 12 more 
W/System.err(  901): Caused by: java.security.InvalidAlgorithmParameterException: the trust anchors set is empty 
W/System.err(  901):    at java.security.cert.PKIXParameters.checkTrustAnchors(PKIXParameters.java:645) 
W/System.err(  901):    at java.security.cert.PKIXParameters.<init>(PKIXParameters.java:89) 
W/System.err(  901):    at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.<init>(TrustManagerImpl.java:89) 
W/System.err(  901):    at org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl.engineGetTrustManagers(TrustManagerFactoryImpl.java:134) 
W/System.err(  901):    at javax.net.ssl.TrustManagerFactory.getTrustManagers(TrustManagerFactory.java:226)W/System.err(  901):     at org.apache.http.conn.ssl.SSLSocketFactory.createTrustManagers(SSLSocketFactory.java:263) 
W/System.err(  901):    at org.apache.http.conn.ssl.SSLSocketFactory.<init>(SSLSocketFactory.java:190) 
W/System.err(  901):    at org.apache.http.conn.ssl.SSLSocketFactory.<init>(SSLSocketFactory.java:216) 
W/System.err(  901):    at me.harrisonlee.test.ssl.MainActivity.connect(MainActivity.java:107) 
W/System.err(  901):    ... 2 more



HttpComponents का एपीआई बदल गया है। यह नीचे दिए गए कोड के साथ काम करता है।

public static HttpClient getTestHttpClient() {
    try {
        SSLSocketFactory sf = new SSLSocketFactory(new TrustStrategy(){
            @Override
            public boolean isTrusted(X509Certificate[] chain,
                    String authType) throws CertificateException {
                return true;
            }
        }, new AllowAllHostnameVerifier());

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("https",8444, sf));
        ClientConnectionManager ccm = new ThreadSafeClientConnManager(registry);
        return new DefaultHttpClient(ccm);
    } catch (Exception e) {
        e.printStackTrace();
        return new DefaultHttpClient();
    }
}



Any body still struggling with StartCom SSL Certificates on Android 2.1 visit https://www.startssl.com/certs/ and download the ca.pem, now in the answer provided by replace

`export CLASSPATH=bcprov-jdk16-145.jar
 CERTSTORE=res/raw/mystore.bks
      if [ -a $CERTSTORE ]; then
          rm $CERTSTORE || exit 1
      fi
 keytool \
  -import \
  -v \
  -trustcacerts \
  -alias 0 \
  -file <(openssl x509 -in mycert.pem) \
  -keystore $CERTSTORE \
  -storetype BKS \
  -provider org.bouncycastle.jce.provider.BouncyCastleProvider \
  -providerpath /usr/share/java/bcprov.jar \
  -storepass some-password`

साथ में

 `export CLASSPATH=bcprov-jdk16-145.jar
 CERTSTORE=res/raw/mystore.bks
      if [ -a $CERTSTORE ]; then
          rm $CERTSTORE || exit 1
      fi
 keytool \
  -import \
  -v \
  -trustcacerts \
  -alias 0 \
  -file <(openssl x509 -in ca.pem) \
  -keystore $CERTSTORE \
  -storetype BKS \
  -provider org.bouncycastle.jce.provider.BouncyCastleProvider \
  -providerpath /usr/share/java/bcprov.jar \
  -storepass some-password`

Should work out of the box. I was struggling it for over a day even after a perfect answer by .. Hope this helps someone...




मैं उन लोगों के लिए प्रतिक्रिया जोड़ रहा हूं जो httpclient-4.5 का उपयोग करते हैं, और शायद 4.4 के लिए भी काम करता है।

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.fluent.ContentResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;



public class HttpClientUtils{

public static HttpClient getHttpClientWithoutSslValidation_UsingHttpClient_4_5_2() {
    try {
        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(null, new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                return true;
            }
        });
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(), new NoopHostnameVerifier());
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); 
        return httpclient;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
}



Simply use this -

public DefaultHttpClient wrapClient(HttpClient base) {
    try {
        SSLContext ctx = SSLContext.getInstance("TLS");
        X509TrustManager tm = new X509TrustManager() {
        public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { }

        public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { }

        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    };
    ctx.init(null, new TrustManager[]{tm}, null);
    SSLSocketFactory ssf = new SSLSocketFactory(ctx);
    ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    ClientConnectionManager ccm = base.getConnectionManager();
    SchemeRegistry sr = ccm.getSchemeRegistry();
    sr.register(new Scheme("https", ssf, 443));
    return new DefaultHttpClient(ccm, base.getParams());
} catch (Exception ex) {
    return null;
}
}



यह विचार अच्छा नहीं है। किसी प्रमाण पत्र पर भरोसा करना केवल एसएसएल का उपयोग करने से थोड़ा बेहतर है। जब आप कहते हैं, "मैं चाहता हूं कि मेरा ग्राहक किसी प्रमाण पत्र को स्वीकार करे (क्योंकि मैं केवल एक सर्वर को इंगित करता हूं)" आप मानते हैं कि इसका मतलब यह है कि किसी भी तरह से "एक सर्वर" को इंगित करना सुरक्षित है, जो कि यह सार्वजनिक नेटवर्क पर नहीं है।

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

आपको keytool का उपयोग करके एक जेक्स में सार्वजनिक प्रमाणपत्र जोड़ने पर विचार करना चाहिए, और इसका उपयोग अपने सॉकेट फैक्ट्री को बनाने के लिए करना चाहिए, जैसे कि:

    KeyStore ks = KeyStore.getInstance("JKS");

    // get user password and file input stream
    char[] password = ("mykspassword")).toCharArray();
    ClassLoader cl = this.getClass().getClassLoader();
    InputStream stream = cl.getResourceAsStream("myjks.jks");
    ks.load(stream, password);
    stream.close();

    SSLContext sc = SSLContext.getInstance("TLS");
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");

    kmf.init(ks, password);
    tmf.init(ks);

    sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(),null);

    return sc.getSocketFactory();

इसके लिए बाहर देखने के लिए एक चेतावनी है। प्रमाणपत्र अंततः समाप्त हो जाएगा, और कोड उस समय काम करना बंद कर देगा। आप आसानी से निर्धारित कर सकते हैं कि यह प्रमाण को देखकर कब होगा।




work with all https

httpClient = new DefaultHttpClient();

SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
    public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { }

    public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { }

    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }
};

ctx.init(null, new TrustManager[]{tm}, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, ssf));



4.1.2 httpclient कोड का उपयोग करके यहां एक बहुत ही सरल संस्करण है। इसके बाद आप फिट होने वाले किसी भी ट्रस्ट एल्गोरिदम में संशोधित किए जा सकते हैं।

public static HttpClient getTestHttpClient() {
    try {
        SSLSocketFactory sf = new SSLSocketFactory(new TrustStrategy(){
            @Override
            public boolean isTrusted(X509Certificate[] chain,
                    String authType) throws CertificateException {
                return true;
            }
        });
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("https", 443, sf));
        ClientConnectionManager ccm = new ThreadSafeClientConnManager(registry);
        return new DefaultHttpClient(ccm);
    } catch (Exception e) {
        return new DefaultHttpClient();
    }
}



For those who would like to allow all certificates to work (for testing purposes) over OAuth, follow these steps:

1) Download the source code of the Android OAuth API here: https://github.com/kaeppler/signpost

2) Find the file "CommonsHttpOAuthProvider" class

3) Change it as below:

public class CommonsHttpOAuthProvider extends AbstractOAuthProvider {

private static final long serialVersionUID = 1L;

private transient HttpClient httpClient;

public CommonsHttpOAuthProvider(String requestTokenEndpointUrl, String accessTokenEndpointUrl,
        String authorizationWebsiteUrl) {
    super(requestTokenEndpointUrl, accessTokenEndpointUrl, authorizationWebsiteUrl);


    //this.httpClient = new DefaultHttpClient();//Version implemented and that throws the famous "javax.net.ssl.SSLException: Not trusted server certificate" if the certificate is not signed with a CA
    this.httpClient = MySSLSocketFactory.getNewHttpClient();//This will work with all certificates (for testing purposes only)
}

The "MySSLSocketFactory" above is based on the accepted answer. To make it even easier, here goes the complete class:

package com.netcomps.oauth_example;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;

//http://.com/questions/2642777/trusting-all-certificates-using-httpclient-over-https
public class MySSLSocketFactory extends SSLSocketFactory {

    SSLContext sslContext = SSLContext.getInstance("TLS");

public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {

    super(truststore);
    TrustManager tm = new X509TrustManager() {

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

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

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    };

    sslContext.init(null, new TrustManager[] { tm }, null);
}

@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
    return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}

@Override
public Socket createSocket() throws IOException {
    return sslContext.getSocketFactory().createSocket();
}



public static HttpClient getNewHttpClient() {

    try {
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null, null);

        SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
        sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", sf, 443));

        ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

        return new DefaultHttpClient(ccm, params);

    } catch (Exception e) {
        return new DefaultHttpClient();
    }
}

}

उम्मीद है कि यह किसी की मदद करता है।






Related