美文网首页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