如果证书是从特定的自签名 CA 签名的,请检查 WebViewClient 的 onReceivedSslError() 方法

Check in the onReceivedSslError() method of a WebViewClient if a certificate is signed from a specific self-signed CA(如果证书是从特定的自签名 CA 签名的,请检查 WebViewClient 的 onReceivedSslError() 方法)
本文介绍了如果证书是从特定的自签名 CA 签名的,请检查 WebViewClient 的 onReceivedSslError() 方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想覆盖 WebViewClientonReceivedSslError().在这里,我想检查 error.getCertificate() 证书是否由自签名 CA 签名,仅在这种情况下,调用 handler.proceed().在伪代码中:

I would like to override the onReceivedSslError() of a WebViewClient. Here I want to check if the error.getCertificate() certificate is signed from a self-signed CA and, only in this case, call the handler.proceed(). In pseudo-code:

@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
    SslCertificate serverCertificate = error.getCertificate();

    if (/* signed from my self-signed CA */) {
        handler.proceed();
    }
    else {
        super.onReceivedSslError(view, handler, error);
    }
}

我的 CA 的公钥保存在名为 rootca.bks 的 BouncyCastle 资源中.我该怎么办?

The public key of my CA is saved in a BouncyCastle resource called rootca.bks. How can I do?

推荐答案

我觉得你可以尝试如下:

I think you can try as the following:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    try {
        WebView webView = (WebView) findViewById(R.id.webView);
        if (webView != null) {
            // Get cert from raw resource...
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream caInput = getResources().openRawResource(R.raw.rootca); // stored at appsrcmain
es
aw
            final Certificate certificate = cf.generateCertificate(caInput);
            caInput.close();

            String url = "https://www.yourserver.com";
            webView.setWebViewClient(new WebViewClient() {                    
                @Override
                public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                    // Get cert from SslError
                    SslCertificate sslCertificate = error.getCertificate();
                    Certificate cert = getX509Certificate(sslCertificate);
                    if (cert != null && certificate != null){
                        try {
                            // Reference: https://developer.android.com/reference/java/security/cert/Certificate.html#verify(java.security.PublicKey)
                            cert.verify(certificate.getPublicKey()); // Verify here...
                            handler.proceed();
                        } catch (CertificateException | NoSuchAlgorithmException | InvalidKeyException | NoSuchProviderException | SignatureException e) {
                            super.onReceivedSslError(view, handler, error);
                            e.printStackTrace();
                        }
                    } else {
                        super.onReceivedSslError(view, handler, error);
                    }
                }
            });

            webView.loadUrl(url);
        }
    } catch (Exception e){
        e.printStackTrace();
    }
}

// credits to @Heath Borders at http://stackoverflow.com/questions/20228800/how-do-i-validate-an-android-net-http-sslcertificate-with-an-x509trustmanager
private Certificate getX509Certificate(SslCertificate sslCertificate){
    Bundle bundle = SslCertificate.saveState(sslCertificate);
    byte[] bytes = bundle.getByteArray("x509-certificate");
    if (bytes == null) {
        return null;
    } else {
        try {
            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
            return certFactory.generateCertificate(new ByteArrayInputStream(bytes));
        } catch (CertificateException e) {
            return null;
        }
    }
}

如果验证失败,logcat会有一些信息如java.security.SignatureException: Signature was not verifyed...

If failed validation, logcat will have some information such as java.security.SignatureException: Signature was not verified...

如果成功,这里是截图:

If success, here's a screenshot:

这篇关于如果证书是从特定的自签名 CA 签名的,请检查 WebViewClient 的 onReceivedSslError() 方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Why local notification is not firing for UNCalendarNotificationTrigger(为什么没有为UNCalendarNotificationTrigger触发本地通知)
How to target newer versions in .gitlab-ci.yml using auto devops (java 11 instead of 8 and Android 31 instead of 29)(如何在.gitlab-ci.yml中使用自动开发工具(Java 11而不是8,Android 31而不是29)瞄准较新的版本)
Android + coreLibraryDesugaring: which Java 11 APIs can I expect to work?(Android+core LibraryDesugering:我可以期待哪些Java 11API能够工作?)
How to render something in an if statement React Native(如何在If语句中呈现某些内容Reaction Native)
How can I sync two flatList scroll position in react native(如何在本机Reaction中同步两个平面列表滚动位置)
How to stop UIBarButtonItem text from truncating?(如何阻止UIBarButtonItem文本被截断?)