Android WebView加载https网址导致空白屏幕

时间:2017-08-24 19:04:20

标签: android ssl webview

WebView可以正常处理http请求,还可以https知道可信赖的网站,例如https://www.online.citibank.co.in/ 但我试图访问从第三方发出的CA的私人网站,它给了空白屏幕。证书通过SD卡安装到手机上,并列在受信任的证书列表下。

当我将证书添加到TrustManager后使用HttpsURLConnection尝试相同的URL时,它工作正常(能够获取内容)。

以下是WebView和HttpsURLConnection的代码段。

HttpsURLConnection:以下代码工作正常,可以从网址获取内容(我无法共享网址,因为无法从外部访问)

try
{
    SSLContext context = null;

    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    InputStream caInput = getResources().openRawResource(R.raw.mi_net);
    Certificate ca;
    try {
        ca = cf.generateCertificate(caInput);
    } finally {
        caInput.close();
    }

    // Create a KeyStore containing our trusted CAs
    String keyStoreType = KeyStore.getDefaultType();
    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    keyStore.load(null, null);
    keyStore.setCertificateEntry("ca", ca);

    // Create a TrustManager that trusts the CAs in our KeyStore
    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
    tmf.init(keyStore);

    // Create an SSLContext that uses our TrustManager
    context = SSLContext.getInstance("TLS");
    context.init(null, tmf.getTrustManagers(), null);

    url = new URL(urlStr);
    HttpsURLConnection con = (HttpsURLConnection) url.openConnection();  
    con.setSSLSocketFactory(context.getSocketFactory());
    con.setInstanceFollowRedirects(true);

    con.setDoOutput(false);
    con.setConnectTimeout(1000);
    String responseMsg = con.getResponseMessage();
    response = con.getResponseCode();
    is = con.getInputStream();
}

WebView:不起作用,称为回调onReceivedSslError

{
    WebSettings viewSettings = webView.getSettings();
    viewSettings.setJavaScriptEnabled(true);
    viewSettings.setAllowContentAccess(true);
    viewSettings.setBuiltInZoomControls(false);
    webView.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
    webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
    webView.loadUrl(sameURL);

    webView.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageStarted(final WebView view, final String url, Bitmap favicon) {
            Log.d("ann", "onPageStarted");

        }

        @Override
        public void onPageFinished(final WebView view, String url) {
            Log.d("ann", "inside onPageFinished");
        }

        @Override
        public void onReceivedError(WebView view, int errorCode,
                                    String description, String failingUrl) {

            if (!failingUrl.startsWith("mailto:")) {
                webView.loadUrl("file:///android_asset/html/error.html");
            }

        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler,
                                       SslError error) {
            super.onReceivedSslError(view, handler, error);
            Log.d("ann","SSL error");

            handler.proceed();
        }

    });}
}

请帮我提一下建议。 WebViewClient异常为 I / X509Util:无法验证证书链,错误:java.security.cert.CertPathValidatorException:未找到证书路径的信任锚。

1 个答案:

答案 0 :(得分:0)

对于HttpsUrlConnection,您将从文件创建证书并在运行时进行设置。

Webview必须使用系统中的任何内容。

这是一个类似的问题,提出了一个解决方法:

Check in the onReceivedSslError() method of a WebViewClient if a certificate is signed from a specific self-signed CA