Android中Https通信实现_webview实现证书校验

版权声明:本博客主要记录学习笔记和遇到的一些问题解决方案,转载请注明出处! https://blog.csdn.net/u010982507/article/details/86165390

使用OkHttp或者HttpUrlConnection验证证书和域名的实现已经在 https://mp.csdn.net/mdeditor/85266096 中讲解了,那么有的App中使用了webview加载html,在html中使用ajax请求Https服务,又如何进行证书的安全校验呢?
本文主要讲解webview实现Https自制证书的校验。
我们使用Android的webview的时候会设置一个WebViewClient,而如果请求Https发生错误的时候,就会调用WebViewClientonReceivedSslError方法,如下所示:

WebView webView = new WebView(getContext());
  webView.setWebViewClient(new WebViewClient(){
     @Override
     public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
         super.onReceivedSslError(view, handler, error);
         
     }
});

super.onReceivedSslError(view, handler, error);默认继承父类的实现,父类的实现是handler.cancel();取消通信。所以我们要做的就是在onReceivedSslError方法中进行证书校验。

onReceivedSslError方法参数分析

  • WebView view参数
    这个没什么可说的,就是当前的webview对象。
  • SslErrorHandler handler参数
    点进源码可以看到,就一个构造方法和两个类方法。proceed()方法是允许所有网络访问,cancel()方法是取消所有网络访问。
public class SslErrorHandler extends Handler {

    /**
     * @hide Only for use by WebViewProvider implementations.
     */
    @SystemApi
    public SslErrorHandler() {}

    /**
     * Proceed with the SSL certificate.
     */
    public void proceed() {}

    /**
     * Cancel this request and all pending requests for the WebView that had
     * the error.
     */
    public void cancel() {}
}
  • SslError error参数
    点进SslError源码可以看到这个类的属性和方法
    主要属性有:
    SSL_NOTYETVALID:证书不合法
    SSL_EXPIRED:证书超出有效期
    SSL_IDMISMATCH:域名不匹配
    SSL_UNTRUSTED:不受信的证书
    SSL_DATE_INVALID:证书日期无效
    SSL_INVALID:一般性错误
    除了几个构造方法外,主要方法有:
    getUrl():获取当前请求的url
    getPrimaryError():获取错误类型
    getCertificate():获取当前证书

证书的sha256值校验

判断逻辑是:
1、获取当前webview的证书的sha256值
2、获取客户端证书的sha256值
3、对比两个证书的sha256值,如果相等,则调用handler.proceed()方法,如果不相等,则调用弹出提示框,并退出应用程序。

WebView webView = new WebView(getContext());
  webView.setWebViewClient(new WebViewClient(){
     @Override
     public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
         String certSha256 = SSLSocketCert.getSSLCertSHA256FromCert(view.getContext().getAssets().open("client.crt"));
         String serverSha256 = SSLSocketCert.getSSLCertFromServer(error.getCertificate());
         if (certSha256.equalsIgnoreCase(serverSha256)) {
             handler.proceed();
         } else {
             DialogUtil.showSingleDialog(view.getContext(), "警告", "证书校验失败", false, "退出", new DialogInterface.OnClickListener() {
                 @Override
                 public void onClick(DialogInterface dialog, int which) {
                     System.exit(0);
                 }
             });
         }
     }
});

上面代码用到了SSLSocketCertDialogUtil工具类,DialogUtil可以使用自己的,SSLSocketCert已上传到
https://download.csdn.net/download/u010982507/10907473

猜你喜欢

转载自blog.csdn.net/u010982507/article/details/86165390