• 【第六篇】Volley之https相关


    Volley之https信任所有证书实现:

    public class HttpsTrustManager implements X509TrustManager {
    
        private static TrustManager[] trustManagers;
        private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[]{};
    
        @Override
        public void checkClientTrusted(
                java.security.cert.X509Certificate[] x509Certificates, String s)
                throws java.security.cert.CertificateException {
    
        }
    
        @Override
        public void checkServerTrusted(
                java.security.cert.X509Certificate[] x509Certificates, String s)
                throws java.security.cert.CertificateException {
    
        }
    
        public boolean isClientTrusted(X509Certificate[] chain) {
            return true;
        }
    
        public boolean isServerTrusted(X509Certificate[] chain) {
            return true;
        }
    
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return _AcceptedIssuers;
        }
    
        public static void allowAllSSL() {
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
    
                @Override
                public boolean verify(String arg0, SSLSession arg1) {
                    return true;
                }
    
            });
    
            SSLContext context = null;
            if (trustManagers == null) {
                trustManagers = new TrustManager[]{new HttpsTrustManager()};
            }
    
            try {
                context = SSLContext.getInstance("TLS");
                context.init(null, trustManagers, new SecureRandom());
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }
    
            HttpsURLConnection.setDefaultSSLSocketFactory(context
                    .getSocketFactory());
        }
    
    }

    代码中调用方法如下:

    HttpsTrustManager.allowAllSSL();//主要是这行实现信任所有证书的操作
    String  tag_string_req = "string_req";
    StringRequest strReq = new StringRequest(Request.Method.POST,
            your_https_url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            Log.d(TAG, "response :"+response);
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            VolleyLog.d(TAG, "Error: " + error.getMessage());
        }
    }){
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<String, String>();
            params.put("username", "max");
            params.put("password", "123456");
            return params;
        }
    };
    AppController.getInstance().addToRequestQueue(strReq, tag_string_req);

    信任指定的证书文件

    HurlStack代码里面有如下方法:

     /**
         * @param urlRewriter Rewriter to use for request URLs
         * @param sslSocketFactory SSL factory to use for HTTPS connections
         * HurlStack这个类的构造大家就会发现其实volley可以支持https了,同样位于toolbox包下
         */
        public HurlStack(UrlRewriter urlRewriter, SSLSocketFactory sslSocketFactory) {
            mUrlRewriter = urlRewriter;
            mSslSocketFactory = sslSocketFactory;
        }
      /**
         * Opens an {@link HttpURLConnection} with parameters.
         * @param url
         * @return an open connection
         * @throws IOException
         */
        private HttpURLConnection openConnection(URL url, Request<?> request) throws IOException {
            HttpURLConnection connection = createConnection(url);
    
            int timeoutMs = request.getTimeoutMs();
            connection.setConnectTimeout(timeoutMs);
            connection.setReadTimeout(timeoutMs);
            connection.setUseCaches(false);
            connection.setDoInput(true);
    
            // use caller-provided custom SslSocketFactory, if any, for HTTPS
            if ("https".equals(url.getProtocol()) && mSslSocketFactory != null) {
                ((HttpsURLConnection)connection).setSSLSocketFactory(mSslSocketFactory);
            }
    
            return connection;
        }

    在https协议的情况下,保证mSslSocketFactory 不为null,因此主要的问题是传进去sslSocketFactory这个参数。

    stackoverflow上面有个产生这个内容的工具类:

    private TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers) {
            final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0];
            return new TrustManager[]{
                    new X509TrustManager() {
                        public X509Certificate[] getAcceptedIssuers() {
                            return originalTrustManager.getAcceptedIssuers();
                        }
    
                        public void checkClientTrusted(X509Certificate[] certs, String authType) {
                            try {
                                originalTrustManager.checkClientTrusted(certs, authType);
                            } catch (CertificateException e) {
                                e.printStackTrace();
                            }
                        }
    
                        public void checkServerTrusted(X509Certificate[] certs, String authType) {
                            try {
                                originalTrustManager.checkServerTrusted(certs, authType);
                            } catch (CertificateException e) {
                                e.printStackTrace();
                            }
                        }
                    }
            };
        }
    
    private SSLSocketFactory getSSLSocketFactory_Certificate(String keyStoreType, int keystoreResId)
            throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException {
    
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        InputStream caInput = getResources().openRawResource(keystoreResId);
    
        Certificate ca = cf.generateCertificate(caInput);
        caInput.close();
    
        if (keyStoreType == null || keyStoreType.length() == 0) {
            keyStoreType = KeyStore.getDefaultType();
        }
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);
    
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);
    
        TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());
    
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, wrappedTrustManagers, null);
    
        return sslContext.getSocketFactory();
    }
    
    private SSLSocketFactory getSSLSocketFactory_KeyStore(String keyStoreType, int keystoreResId, String keyPassword)
                throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException {
    
            InputStream caInput = getResources().openRawResource(keystoreResId);
    
            // creating a KeyStore containing trusted CAs
    
            if (keyStoreType == null || keyStoreType.length() == 0) {
                keyStoreType = KeyStore.getDefaultType();
            }
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    
            keyStore.load(caInput, keyPassword.toCharArray());
    
            // creating a TrustManager that trusts the CAs in the KeyStore
    
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);
    
            TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());
    
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, wrappedTrustManagers, null);
    
            return sslContext.getSocketFactory();
        }

    调用后面两个,就能获取SSLSocketFactory 内容,使用如下:

    SSLSocketFactory sslSocketFactory = getSSLSocketFactory_KeyStore("BKS", R.raw.androidbksv1, "123456789");
    SSLSocketFactory sslSocketFactory = getSSLSocketFactory_Certificate("BKS", R.raw.androidbksv1_cert);

    http://stackoverflow.com/questions/32154115/android-volley-self-signed-https-trust-anchor-for-certification-path-not-found

  • 相关阅读:
    入门activiti-------1简单运行
    JS对象、构造器函数和原型对象之间的关系
    myeclipse配背景色
    maven的pom.xml文件错误
    oracleXE简易版---使用基础
    ognl表达式注意事项
    Executors、ExecutorService、ThreadPoolExecutor
    ThreadPoolExecutor
    Phaser相位(工具的实战案例使用)
    ForkJoin
  • 原文地址:https://www.cnblogs.com/androidsuperman/p/4811695.html
Copyright © 2020-2023  润新知