美文网首页AndroidAndroid进阶
关于webview加载https的正确使用方式

关于webview加载https的正确使用方式

作者: one_cup | 来源:发表于2017-03-28 19:00 被阅读203次

    关于webview加载https的正确使用方式

    头几天同事遇到webview加载https出现空白页面的情况,简单查了一下发现是因为所使用的证书没有本地授信,同样的网址复制到浏览器中会弹出一个对话框提示查看或者继续,而webview中却没有,网上的方式就是在webviewclient中重写onReceivedSslError这个方法,然后调用handler.proceed();授信就可以,不过这存在一个问题就是没有对加载的https证书进行校验,就直接通过了,容易受到攻击或者代理拦截之类的,所有加上了一层证书的校验,具体的方式看代码:

    @Override
      public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
          SslCertificate certificate = error.getCertificate();
          String cName = certificate.getIssuedBy().getCName();
          String uName = certificate.getIssuedTo().getOName();
          if(HttpsUtils.checkSslCertificate(certificate)&&
                  cName.equals(getResources().getString(R.string.ssl_issueby_name))&&
                  uName.equals(getResources().getString(R.string.company_name))){
              handler.proceed();
          }
      }
    

    原理就是通过SslError取到https的证书,然后分别取使用者和颁发者的名字,进行对比,同时也会对比这个证书与本地的一个证书的职位是否相同。通过方法HttpsUtils.checkSslCertificate():

    public static boolean checkSslCertificate(SslCertificate certificate) {
            Bundle bundle = SslCertificate.saveState(certificate);
            byte[] bytes = bundle.getByteArray("x509-certificate");
            if (bytes != null) {
                try {
                    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
                    Certificate ce = certificateFactory.generateCertificate(new ByteArrayInputStream(bytes));
                    MessageDigest instance = MessageDigest.getInstance("SHA-256");
                    byte[] digest = instance.digest(ce.getEncoded());
                    byte[] local = instance.digest(localCertificate.getEncoded());
                    return Arrays.equals(local, digest);
                } catch (Exception e) {
                }
            }
            return false;
        }
    

    其中的localCertificate就是通过读取本地文件而获得的一个证书对象,对比两个证书的指纹是否相同。HttpsUtils这个类是使用Okhttp进行请求时,初始化sslfactory和trustmanager这两个对象的,在获取TrustManager时会读取本地文件生成一个证书,赋值就可以了:

    一共有三重校验,证书指纹,颁发者和使用者,基本可以保证安全。

    相关文章

      网友评论

        本文标题:关于webview加载https的正确使用方式

        本文链接:https://www.haomeiwen.com/subject/pecsottx.html