GooglePlay SSL Error Handler
应用上架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() {@Overridepublic void onClick(DialogInterface dialog, int which) {handler.proceed();} }); builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {@Overridepublic 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 checkBundle 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;}}}