GooglePlay SSL Error Handler

在App中使用WebView加载HTTPSH5页面时遇到SSL证书错误,导致白屏。文章提供了两种解决方案:1)显示对话框让用户选择是否继续;2)将证书放入应用的res/raw文件夹并加载。第一种方法在接收到SSL错误时提示用户,第二种方法通过加载应用程序内的证书来处理错误。

应用上架GooglePlay 收到邮件提示

 

出现这个原因是因为我在app中使用webview加载Https的H5界面,在onReceivedSslError()中处理SslErrorHandler时,出现白屏现象,原因是webview默认在加载有证书验证的url时,会默认使用handler.cancel()进行拦截操作,这里只需要改成handler.proceed()。

2种解决方式

1.常规解决方式 :

出现在错误的时候让用户同意

final AlertDialog.Builder builder = new AlertDialog.Builder(HomeWebActivity.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();

2.第二种加载https 证书

证书一般常规可以问前端或者后端要。参考 从网页中获取Ssl证书_NextWarm的博客-CSDN博客)拿到将证书(.cer文件)复制到应用程序的res / raw文件夹中

private static final int[] CERTIFICATES = {
        R.raw.cardhobby,   // you can put several certificates
};
private ArrayList<SslCertificate> certificates = new ArrayList<>();

private void loadSSLCertificates() {
    try {
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        for (int rawId : CERTIFICATES) {
            InputStream inputStream = getResources().openRawResource(rawId);
            InputStream certificateInput = new BufferedInputStream(inputStream);
            try {
                Certificate certificate = certificateFactory.generateCertificate(certificateInput);
                if (certificate instanceof X509Certificate) {
                    X509Certificate x509Certificate = (X509Certificate) certificate;
                    SslCertificate sslCertificate = new SslCertificate(x509Certificate);
                    certificates.add(sslCertificate);
                } else {
                }
            } catch (CertificateException exception) {
            } finally {
                try {
                    certificateInput.close();
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    } catch (CertificateException e) {
        e.printStackTrace();
    }
}

binding.webview.setWebViewClient(new WebViewClient() {
   public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
       //handler.cancel(); // Android默认的处理方式
      // handler.proceed();  // 接受所有网站的证书
       //handleMessage(Message msg); // 进行其他处理
       SslCertificate serverCertificate = error.getCertificate();
       Bundle serverBundle = SslCertificate.saveState(serverCertificate);
       for (SslCertificate appCertificate : certificates) {
           if (TextUtils.equals(serverCertificate.toString(), appCertificate.toString())) { // First fast check
               Bundle appBundle = SslCertificate.saveState(appCertificate);
               Set<String> keySet = appBundle.keySet();
               boolean matches = true;
               for (String key : keySet) {
                   Object serverObj = serverBundle.get(key);
                   Object appObj = appBundle.get(key);
                   if (serverObj instanceof byte[] && appObj instanceof byte[]) {     // key "x509-certificate"
                       if (!Arrays.equals((byte[]) serverObj, (byte[]) appObj)) {
                           matches = false;
                           break;
                       }
                   } else if ((serverObj != null) && !serverObj.equals(appObj)) {
                       matches = false;
                       break;
                   }
               }
               if (matches) {
                   handler.proceed();
                   return;
               }
           }
       }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值