美文网首页
给安卓OKHTTP库添加HTTPS证书验证

给安卓OKHTTP库添加HTTPS证书验证

作者: Eternity岚 | 来源:发表于2019-04-09 17:08 被阅读0次

    码字辛苦!转载请注明出处!

    网传的使用sslSocketFactory方法的验证方式已经过时了,因为使用这个方法会使用反射机制寻找X509信任管理类,消耗了不必要的性能。

    新的方法名称依然叫sslSocketFactory,但是会传入信任管理类数组中的第一条,这个博主已在OKHTTP的GITHUB样例源码中求证,请各位放心使用~

    这里放上博主封装的工具,支持传入字符串证书、传入RAW资源目录下的证书、批量添加证书和信任所有证书的功能。

    使用方法:

                //信任所有证书
                HTTPSCerUtils.setTrustAllCertificate(okHttpBuilder);
     
                //信任raw资源目录下的证书
                HTTPSCerUtils.setCertificate(context, okHttpBuilder, R.raw.rootca);
     
                //传入证书字符串
                HTTPSCerUtils.setCertificate(context,okHttpBuilder,"!@$#@!$@#^@^#!");
    

    工具类:

    
    import android.content.Context;
    
    import java.io.ByteArrayInputStream;
    import java.io.InputStream;
    import java.security.KeyStore;
    import java.security.SecureRandom;
    import java.security.cert.Certificate;
    import java.security.cert.CertificateException;
    import java.security.cert.CertificateFactory;
    import java.security.cert.X509Certificate;
    
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.TrustManagerFactory;
    import javax.net.ssl.X509TrustManager;
    
    import okhttp3.OkHttpClient;
    
    public class HTTPSCerUtils {
    
        //信任所有证书
        public static void setTrustAllCertificate(OkHttpClient.Builder okHttpClientBuilder) {
            try {
                SSLContext sc = SSLContext.getInstance("TLS");
                X509TrustManager trustAllManager = new 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];
                    }
                };
                sc.init(null, new TrustManager[]{trustAllManager}, new SecureRandom());
                okHttpClientBuilder.sslSocketFactory(sc.getSocketFactory(), trustAllManager);
                //如果需要兼容安卓5.0以下,可以使用这句
                //okHttpClientBuilder.sslSocketFactory(new TLSSocketFactory(), trustAllManager);
                okHttpClientBuilder.hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        //只信任指定证书(传入字符串)
        public static void setCertificate(Context context, OkHttpClient.Builder okHttpClientBuilder, String cerStr) {
            try {
                CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
                ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(cerStr.getBytes());
                Certificate ca = certificateFactory.generateCertificate(byteArrayInputStream);
    
                KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                keyStore.load(null, null);
                keyStore.setCertificateEntry("ca", ca);
    
                byteArrayInputStream.close();
    
                TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                tmf.init(keyStore);
    
                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
                okHttpClientBuilder.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) tmf.getTrustManagers()[0]);
                okHttpClientBuilder.hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        //只信任指定证书(传入raw资源ID)
        public static void setCertificate(Context context, OkHttpClient.Builder okHttpClientBuilder, int cerResID) {
            try {
                CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
                InputStream inputStream = context.getResources().openRawResource(cerResID);
                Certificate ca = certificateFactory.generateCertificate(inputStream);
    
                KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                keyStore.load(null, null);
                keyStore.setCertificateEntry("ca", ca);
    
                inputStream.close();
    
                TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                tmf.init(keyStore);
    
                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
                okHttpClientBuilder.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) tmf.getTrustManagers()[0]);
                okHttpClientBuilder.hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        //批量信任证书
        public static void setCertificates(Context context, OkHttpClient.Builder okHttpClientBuilder, int... cerResIDs) {
            try {
                CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    
                KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                keyStore.load(null, null);
                for (int i = 0; i < cerResIDs.length; i++) {
                    Certificate ca = certificateFactory.generateCertificate(context.getResources().openRawResource(cerResIDs[i]));
                    keyStore.setCertificateEntry("ca" + i, ca);
                }
    
                TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                tmf.init(keyStore);
    
                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
                okHttpClientBuilder.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) tmf.getTrustManagers()[0]);
                okHttpClientBuilder.hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:给安卓OKHTTP库添加HTTPS证书验证

          本文链接:https://www.haomeiwen.com/subject/ylsiiqtx.html