Volley之https相关

来源:互联网 发布:承德县德鸣大数据小镇 编辑:程序博客网 时间:2024/06/07 08:35

转载自:http://www.cnblogs.com/androidsuperman/p/4811695.html


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

0 0
原创粉丝点击