Trusting all certificates using HttpClient over HTTPS

后端 未结 21 2246
北恋
北恋 2020-11-21 04:50

Recently posted a question regarding the HttpClient over Https (found here). I\'ve made some headway, but I\'ve run into new issues. As with my last problem, I

21条回答
  •  抹茶落季
    2020-11-21 05:14

    I'm looked response from "emmby" (answered Jun 16 '11 at 21:29), item #4: "Create a custom SSLSocketFactory that uses the built-in certificate KeyStore, but falls back on an alternate KeyStore for anything that fails to verify with the default."

    This is a simplified implementation. Load the system keystore & merge with application keystore.

    public HttpClient getNewHttpClient() {
        try {
            InputStream in = null;
            // Load default system keystore
            KeyStore trusted = KeyStore.getInstance(KeyStore.getDefaultType()); 
            try {
                in = new BufferedInputStream(new FileInputStream(System.getProperty("javax.net.ssl.trustStore"))); // Normally: "/system/etc/security/cacerts.bks"
                trusted.load(in, null); // no password is "changeit"
            } finally {
                if (in != null) {
                    in.close();
                    in = null;
                }
            }
    
            // Load application keystore & merge with system
            try {
                KeyStore appTrusted = KeyStore.getInstance("BKS"); 
                in = context.getResources().openRawResource(R.raw.mykeystore);
                appTrusted.load(in, null); // no password is "changeit"
                for (Enumeration e = appTrusted.aliases(); e.hasMoreElements();) {
                    final String alias = e.nextElement();
                    final KeyStore.Entry entry = appTrusted.getEntry(alias, null);
                    trusted.setEntry(System.currentTimeMillis() + ":" + alias, entry, null);
                }
            } finally {
                if (in != null) {
                    in.close();
                    in = null;
                }
            }
    
            HttpParams params = new BasicHttpParams();
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
    
            SSLSocketFactory sf = new SSLSocketFactory(trusted);
            sf.setHostnameVerifier(SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
    
            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();
        }
    }
    

    A simple mode to convert from JKS to BKS:

    keytool -importkeystore -destkeystore cacerts.bks -deststoretype BKS -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-jdk16-141.jar -deststorepass changeit -srcstorepass changeit -srckeystore $JAVA_HOME/jre/lib/security/cacerts -srcstoretype JKS -noprompt
    

    *Note: In Android 4.0 (ICS) the Trust Store has changed, more info: http://nelenkov.blogspot.com.es/2011/12/ics-trust-store-implementation.html

提交回复
热议问题