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;
    }
};
上一篇 Android AOP aspectj 配置
下一篇 Android注解使用之ButterKnife 10注解使用介绍
目录
文章列表
1 loonflow工单系统
loonflow工单系统
2
Linux的生成.ssh公私钥
Linux的生成.ssh公私钥
3
Linux firewall-cmd 命令详解
Linux firewall-cmd 命令详解
4
Kibana Grok 调试工具使用
Kibana Grok 调试工具使用
5
Android Gradle配置Debug和Release参数的方法
Android Gradle配置Debug和Release参数的方法
最新评论
一位WordPress评论者
一位WordPress评论者
2月12日
您好,这是一条评论。若需要审核、编辑或删除评论,请访问仪表盘的评论界面。评论者头像来自 Gravatar。