美文网首页android网络请求android基本功
OkHttp使用https,忽略证书验证

OkHttp使用https,忽略证书验证

作者: SyncAny | 来源:发表于2017-02-08 17:36 被阅读2046次
    https

    最近在使用https访问时遇到证书的问题,在调试的时候始终会提示证书不可用,于是查询了一下,忽略证书的验证;

    方法一:

    1.继承SSLSocketFactory ,重写里面的方法;

    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.security.KeyManagementException;
    import java.security.KeyStore;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    
    
    public class SSLSocketFactoryImp extends SSLSocketFactory {
        private SSLContext sslContext = SSLContext.getInstance("SSL");
        private TrustManager trustManager = null;
    
    
        public SSLContext getSSLContext() {
            return sslContext;
        }
    
        public X509TrustManager getTrustManager() {
            return (X509TrustManager)trustManager;
        }
    
        public SSLSocketFactoryImp(KeyStore keyStore) throws NoSuchAlgorithmException, KeyManagementException {
            trustManager = new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
    
                }
    
                @Override
                public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
    
                }
    
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                   //注意这里不能返回null,否则会报错,如下面错误[1]
                    X509Certificate[] x509Certificates = new X509Certificate[0];
                    return x509Certificates;
                }
            };
    
            sslContext.init(null, new TrustManager[]{trustManager}, null);
        }
    
        @Override
        public String[] getDefaultCipherSuites() {
            return new String[0];
        }
    
        @Override
        public String[] getSupportedCipherSuites() {
            return new String[0];
        }
    
        @Override
        public Socket createSocket() throws IOException {
            return sslContext.getSocketFactory().createSocket();
        }
    
        @Override
        public Socket createSocket(Socket socket, String host, int post, boolean autoClose) throws IOException {
            return sslContext.getSocketFactory().createSocket(socket, host, post, autoClose);
        }
    
        @Override
        public Socket createSocket(String s, int i) throws IOException, UnknownHostException {
            return null;
        }
    
        @Override
        public Socket createSocket(String s, int i, InetAddress inetAddress, int i1) throws IOException, UnknownHostException {
            return null;
        }
    
        @Override
        public Socket createSocket(InetAddress inetAddress, int i) throws IOException {
            return null;
        }
    
        @Override
        public Socket createSocket(InetAddress inetAddress, int i, InetAddress inetAddress1, int i1) throws IOException {
            return null;
        }
    }
    

    2.在相应的地方调用,该方法中忽略了我的其他设置,只包含关于ssl的设置,不影响正常使用。

    public static OkHttpClient getClient(Interceptor... interceptor) {
            OkHttpClient.Builder builder = null;
            try {
                builder = new OkHttpClient.Builder();
                //ssl verifier
                KeyStore trustStore;
                trustStore = KeyStore.getInstance(KeyStore
                        .getDefaultType());
                trustStore.load(null, null);
                SSLSocketFactoryImp ssl = new SSLSocketFactoryImp(KeyStore.getInstance(KeyStore.getDefaultType()));
    
                HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                };
    
                builder.sslSocketFactory(ssl.getSSLContext().getSocketFactory(), ssl.getTrustManager())
                .hostnameVerifier(DO_NOT_VERIFY);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return builder.build();
        }
    

    方法二:

    直接利用SSLContext来设置

    X509TrustManager xtm = new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) {
                }
    
                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) {
                }
    
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    X509Certificate[] x509Certificates = new X509Certificate[0];
                    return x509Certificates;
                }
            };
    
            SSLContext sslContext = null;
            try {
                sslContext = SSLContext.getInstance("SSL");
    
                sslContext.init(null, new TrustManager[]{xtm}, new SecureRandom());
    
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }
            HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };
            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .addInterceptor(interceptor)
                    .sslSocketFactory(sslContext.getSocketFactory())
                    .hostnameVerifier(DO_NOT_VERIFY)
                    .build();
    

    错误

    上面说到如果

    public X509Certificate[] getAcceptedIssuers() {
                    X509Certificate[] x509Certificates = new X509Certificate[0];
                    return x509Certificates;
                }
    

    返回null,报错如下:

    AndroidRuntime( 9669): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxxx.android/com.xxxxActivity}: java.lang.NullPointerException: Attempt to get length of null array
    E/AndroidRuntime( 9669):        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2623)
    E/AndroidRuntime( 9669):        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2687)
    E/AndroidRuntime( 9669):        at android.app.ActivityThread.access$800(ActivityThread.java:177)
    E/AndroidRuntime( 9669):        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1557)
    E/AndroidRuntime( 9669):        at android.os.Handler.dispatchMessage(Handler.java:111)
    E/AndroidRuntime( 9669):        at android.os.Looper.loop(Looper.java:199)
    E/AndroidRuntime( 9669):        at android.app.ActivityThread.main(ActivityThread.java:5755)
    E/AndroidRuntime( 9669):        at java.lang.reflect.Method.invoke(Native Method)
    E/AndroidRuntime( 9669):        at java.lang.reflect.Method.invoke(Method.java:372)
    E/AndroidRuntime( 9669):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:982)
    E/AndroidRuntime( 9669):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:777)
    E/AndroidRuntime( 9669): Caused by: java.lang.NullPointerException: Attempt to get length of null array
    E/AndroidRuntime( 9669):        at okhttp3.internal.tls.RealTrustRootIndex.<init>(RealTrustRootIndex.java:31)
    E/AndroidRuntime( 9669):        at okhttp3.internal.Platform.trustRootIndex(Platform.java:100)
    E/AndroidRuntime( 9669):        at okhttp3.internal.Platform$Android.trustRootIndex(Platform.java:249)
    E/AndroidRuntime( 9669):        at okhttp3.OkHttpClient.<init>(OkHttpClient.java:189)
    E/AndroidRuntime( 9669):        at okhttp3.OkHttpClient.<init>(OkHttpClient.java:60)
    E/AndroidRuntime( 9669):        at okhttp3.OkHttpClient$Builder.build(OkHttpClient.java:718)
    

    以上记录,如有错误,还望留言指教!

    相关文章

      网友评论

        本文标题:OkHttp使用https,忽略证书验证

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