Android HTTPS请求 CertPathValidatorException

错误信息

Android使用okhttp等客户端请求https时,证书如果是用来测试(不可信任)的会报出如下问题:

okhttp默认情况下是支持https协议的,不过要注意的是,支持https的网站如果是CA机构颁发的证书,默认情况下是可以信任的,否则不可信任。

javax.net.ssl.SSLHandshakeException:
    java.security.cert.CertPathValidatorException:
        Trust anchor for certification path not found.

解决方案

代理问题

屏蔽证书验证

OkHttp中忽略SSL验证

public OKHttpUtil(Context context) {
    this.context = context;
    buildType = context.getResources().getString(R.string.buildType);
    dbManager = new DBManager(context);
    mOkHttpClient = new OkHttpClient();
    mOkHttpClient.setSslSocketFactory(createSSLSocketFactory()); //**重点**在new OkHttpClient()下添加此代码进行ssl的忽略
}

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 static 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];
    }
}

WebView中忽略SSL验证

webview.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        ptrFrame.refreshComplete();
    }
    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        handler.proceed();//**重点**接受所有证书验证
    }
});

HttpURLConnection中忽略SSL验证

HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setSSLSocketFactory(context.getSocketFactory());
urlConnection.setHostnameVerifier(new HostnameVerifier() {
    @Override
    public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    });
private static InputStream getImageStream(String urlParam) throws Exception {
    URL url = new URL(urlParam);
    HttpURLConnection conn = null;

    //**关键代码**
    //ignore https certificate validation |忽略 https 证书验证
    if (url.getProtocol().toUpperCase().equals("HTTPS")) {
        trustAllHosts();
        HttpsURLConnection https = (HttpsURLConnection) url
                .openConnection();
        https.setHostnameVerifier(InternetUtil.DO_NOT_VERIFY);
        conn = https;
    } else {
        conn = (HttpURLConnection) url.openConnection();
    }

    conn.setConnectTimeout(5 * 1000);
    conn.setRequestMethod("GET");
    if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
        return conn.getInputStream();
    }
    return null;
}

public static void trustAllHosts() {
    // Create a trust manager that does not validate certificate chains
    // Android use X509 cert
    TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[] {};
        }

        public void checkClientTrusted(X509Certificate[] chain,
                                       String authType) throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] chain,
                                       String authType) throws CertificateException {
        }
    } };

    // Install the all-trusting trust manager
    try {
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection
                .setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
};

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/03/18/android-https-request-certpathvalidatorexception/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Android HTTPS请求 CertPathValidatorException
错误信息 Android使用okhttp等客户端请求https时,证书如果是用来测试(不可信任)的会报出如下问题: okhttp默认情况下是支持https协议的,不过要注意的是,……
<<上一篇
下一篇>>
文章目录
关闭
目 录