Okhttp 访问多个自签名证书 HTTPS 地址解决方案

首先参考
Okhttp 访问自签名证书 HTTPS 地址解决方案
上面这篇博客,解决了访问自签名证书的问题。
但是有时候我们要访问过多域名,每个域名的证书又不一样我们应该怎样做呢

public class HttpsUtils {

    private MyTrustManager mMyTrustManager;

    private SSLSocketFactory createSSLSocketFactory() {
        SSLSocketFactory ssfFactory = null;
        try {
            mMyTrustManager = new MyTrustManager();
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{mMyTrustManager}, new SecureRandom());
            ssfFactory = sc.getSocketFactory();
        } catch (Exception ignored) {
            ignored.printStackTrace();
        }

        return ssfFactory;
    }

    //实现X509TrustManager接口
    public class MyTrustManager 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];
        }
    }

    //实现HostnameVerifier接口
    private class TrustAllHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }
   
    /**
     * 获去信任自签证书的trustManager
     *
     * @param ins 自签证书输入流
     * @return 信任自签证书的trustManager
     * @throws GeneralSecurityException
     */
    private X509TrustManager trustManagerForCertificates(InputStream...ins)
            throws GeneralSecurityException {
        //创建证书工厂
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

        //通过证书工厂得到自签证书对象集合
        Collection< Certificate> certificates=new ArrayList<>();

        for(InputStream inputStream:ins) {
            certificates.addAll(certificateFactory.generateCertificates(inputStream));
        }

        if (certificates.isEmpty()) {
            throw new IllegalArgumentException("expected non-empty set of trusted certificates");
        }

        //为证书设置一个keyStore
        char[] password = "password".toCharArray(); // Any password will work.
        KeyStore keyStore = newEmptyKeyStore(password);
        int index = 0;
        //将所有证书放入证书放入keystore中
        for (Certificate certificate : certificates) {
            String certificateAlias = Integer.toString(index++);
            keyStore.setCertificateEntry(certificateAlias, certificate);
        }


        // Use it to build an X509 trust manager.
        //使用包含自签证书信息的keyStore去构建一个X509TrustManager
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
                KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, password);
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
                TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(keyStore);
        TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
        if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
            throw new IllegalStateException("Unexpected default trust managers:"
                    + Arrays.toString(trustManagers));
        }
        return (X509TrustManager) trustManagers[0];
    }

    private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
        try {
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            InputStream in = null; // By convention, 'null' creates an empty key store.
            keyStore.load(null, password);
            return keyStore;
        } catch (IOException e) {
            throw new AssertionError(e);
        }
    }
}

trustManagerForCertificates.(InputStream...ins)为证书的输入流
比如证书文件有两个 1.crt2.crt

Object[] sSlSocketFactoryParams=trustManagerForCertificates(new InputFileStream(new File("1.crt"),new FileInputStream("2.crt")))
//获取到SSLSocketFactory和X509TrustManager
 OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .sslSocketFactory((SSLSocketFactory) sSlSocketFactoryParams[0], (X509TrustManager) sSlSocketFactoryParams[1])
                .build();

你可能感兴趣的:(Okhttp 访问多个自签名证书 HTTPS 地址解决方案)