1. 程式人生 > >Android中進行https請求信任證書問題

Android中進行https請求信任證書問題

前言

    在Android開發專案中難免要進行https請求,如果你也遇到這樣的問題,那麼我想這片部落格能對你有些幫助。

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

    這個異常指的是找不到指定的信任證書。為了避免本地一個一個新增證書的麻煩,尤其是在測試情況下。可以通過一定方法去信任所有證書,免去麻煩。
    注:這個方法雖然省事,但是缺乏安全性,使用前自行考慮。另外,本文所有方法並非自己研究所得,我只是個搬運工,為一些新人們提供方法,也給自己留作筆記.

HtttpsURLConnection框架信任所有https證書

    關於Volley的使用在此不做介紹。
    信任所有證書,只有兩個簡單的步驟:
    1.複製貼上一個工具類,該類源自網路,針對HttpsURLConnection證書信任問題。
    2.在進行聯網請求前呼叫該類allowAllSSL()方法

使用例子

//在進行聯網請求前呼叫該類allowAllSSL()方法
FakeX509TrustManager.allowAllSSL();

送上程式碼

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import
java.security.SecureRandom; import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; /** * Created by Yangmu on 16/12/16. */
public class FakeX509TrustManager 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 { //To change body of implemented methods use File | Settings | File Templates. } @Override public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException { //To change body of implemented methods use File | Settings | File Templates. } 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) { // TODO Auto-generated method stub return true; } }); SSLContext context = null; if (trustManagers == null) { trustManagers = new TrustManager[] { new FakeX509TrustManager() }; } 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()); } }

基於Okhttpclient信任https所有證書

關於Okhttpclient的使用在此依然不做介紹。
    只有兩個簡單的步驟:
    1.複製貼上工具類,針對Okhttpclient證書信任問題。(方法還是源自網路,自行整理)
    2.初始化OkHttpClient物件時進行信任證書的操作
    注意:是基於Okhttpclient,也就是說類似Square公司非常好用的Retrofit的library也能使用。

使用例子

//初始化OkHttpClient物件時進行信任證書的操作
OkHttpClient.Builder mBuilder = new OkHttpClient.Builder();
mBuilder.sslSocketFactory(TrustAllCerts.createSSLSocketFactory());
mBuilder.hostnameVerifier(new TrustAllCerts.TrustAllHostnameVerifier());
client = mBuilder.build();

送上程式碼

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

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/**
* Created by Yangmu on 17/1/19.
*/

public class TrustAllCerts implements 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 new X509Certificate[0];}


    public static SSLSocketFactory createSSLSocketFactory() {
        SSLSocketFactory ssfFactory = null;

        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null,  new TrustManager[] { new TrustAllCerts() }, new SecureRandom());

            ssfFactory = sc.getSocketFactory();
        } catch (Exception e) {
        }

        return ssfFactory;
    }
    public static class TrustAllHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }
}