Android上的Web View是否支持SSL?

Fil*_*erg 31 android

WebView对android 的控制,是否支持SSL?

我正在尝试加载一个使用受信任的ssl证书的网页,但WebView它只是白色.

有什么建议?

chr*_*ris 75

不是专家,只是我在网上找到的东西.根据我的理解,WebView确实支持ssl,但是,空白屏幕表明WebView不相信证书是有效的.这可能发生在自签名的证书或未在android中设置的root身份验证(完全有效的证书不验证).无论如何,如果您使用froyo或更好,您可以尝试以下方式:

import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.SslErrorHandler;
import android.net.http.SslError;

...

engine = (WebView) findViewById(R.id.my_webview);
engine.setWebViewClient(new WebViewClient() {

    @Override
    public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) {
        handler.proceed();
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 要警告在生产应用中实际使用此功能的任何人,这将允许对您的应用进行MitM攻击.更多信息:http://stanford.edu/~pcm2d/blog/ssl.html (6认同)
  • 这篇文章帮了我很多忙!请注意,您需要开发至少2.2并使用以下包括Ssl的东西:import android.webkit.*; import android.net.http.*; (2认同)
  • 感谢您的回答,Google必须检查Play上所有具有完全相同实现的应用,并向开发人员发送警告电子邮件:) (2认同)
  • 是的,实际上我在想,绕过 SSL 错误并不是一个好方法,以后会引起问题。我应该找到一种方法将站点证书添加到手机的根密钥库中,以便可以信任它。但另一方面,创建一个完整的证书存储管理只是为了在 WebView 中显示一个 HTTPS url 似乎有点矫枉过正。对此的任何帮助表示赞赏:) (2认同)

Gow*_*K C 7

Google Play 拒绝了我的应用,然后我就这样做了...

 @Override
    public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {

        try {

            //Get the X509 trust manager from your ssl certificate
            X509TrustManager trustManager = mySslCertificate.getX509TrustManager();

            //Get the certificate from error object
            Bundle bundle = SslCertificate.saveState(error.getCertificate());
            X509Certificate x509Certificate;
            byte[] bytes = bundle.getByteArray("x509-certificate");
            if (bytes == null) {
                x509Certificate = null;
            } else {
                CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
                Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(bytes));
                x509Certificate = (X509Certificate) cert;
            }
            X509Certificate[] x509Certificates = new X509Certificate[1];
            x509Certificates[0] = x509Certificate;

            // check weather the certificate is trusted
            trustManager.checkServerTrusted(x509Certificates, "ECDH_RSA");

            Log.e(TAG, "Certificate from " + error.getUrl() + " is trusted.");
            handler.proceed();
        } catch (Exception e) {
            Log.e(TAG, "Failed to access " + error.getUrl() + ". Error: " + error.getPrimaryError());
            final AlertDialog.Builder builder = new AlertDialog.Builder(WebViewActivity.this);
            String message = "SSL Certificate error.";
            switch (error.getPrimaryError()) {
                case SslError.SSL_UNTRUSTED:
                    message = "The certificate authority is not trusted.";
                    break;
                case SslError.SSL_EXPIRED:
                    message = "The certificate has expired.";
                    break;
                case SslError.SSL_IDMISMATCH:
                    message = "The certificate Hostname mismatch.";
                    break;
                case SslError.SSL_NOTYETVALID:
                    message = "The certificate is not yet valid.";
                    break;
            }
            message += " Do you want to continue anyway?";

            builder.setTitle("SSL Certificate Error");
            builder.setMessage(message);
            builder.setPositiveButton("continue", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    handler.proceed();
                }
            });
            builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    handler.cancel();
                }
            });
            final AlertDialog dialog = builder.create();
            dialog.show();
        }
    }
Run Code Online (Sandbox Code Playgroud)

进行上述更改后,Google Play 接受了我的 apk

并生成您的 ssl 信任管理器请检查此答案


Ana*_*hah 5

要根据更新的安全策略正确处理SSL证书验证,请根据服务器提供的证书更改代码以调用SslErrorHandler.proceed(),否则调用SslErrorHandler.cancel().

例如,我添加了一个警告对话框,以便用户确认并且Google似乎不再显示警告.

    @Override
    public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
    final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
    String message = "SSL Certificate error.";
        switch (error.getPrimaryError()) {
            case SslError.SSL_UNTRUSTED:
                message = "The certificate authority is not trusted.";
                break;
            case SslError.SSL_EXPIRED:
                message = "The certificate has expired.";
                break;
            case SslError.SSL_IDMISMATCH:
                message = "The certificate Hostname mismatch.";
                break;
            case SslError.SSL_NOTYETVALID:
                message = "The certificate is not yet valid.";
                break;
        }
        message += " Do you want to continue anyway?";

        builder.setTitle("SSL Certificate Error");
        builder.setMessage(message);
    builder.setPositiveButton("continue", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.proceed();
        }
    });
    builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.cancel();
        }
    });
    final AlertDialog dialog = builder.create();
    dialog.show();
}
Run Code Online (Sandbox Code Playgroud)

更改后,它不会显示警告.