Android webview手动校验https证书(by 星空武哥)

有些时候由于Android系统的bug或者其他的原因,导致我们的webview不能验证通过我们的https证书,最明显的例子就是华为手机mate7升级到Android7.0后,手机有些网站打不开了,而更新了webview的补丁后就没问题了,充分说明系统的bug对我们混合开发webview加载https地址的影响是巨大的。那么我们怎么去解决这个问题呢?

首先我们去分析一下出现的原因
当webview加载https地址的时候,如果因为证书的问题出错的时候就会走onReceivedSslError()方法

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

而super.onReceivedSslError()默认是

handler.cancel() 就是让加载的页面白屏,所有导致了如果webview校验证书存在异常,android在默认情况下会显示白屏,我们也可调用handler.proceed(),大多时候很多人都是这个处理,但是这也就意味着https证书失去了他存在的意义了。

那么如果你的网站证书是正常的,但是因为系统的bug导致了加载异常,这时候就需要我们手动校验了。
其实我们是可以手动校验网站证书的sha256,如果异常之后校验sha256就执行handler.proceed(),失败就退出应用。
首先我们要获取网站的证书
利用谷歌浏览器,打开网址并且按下“F12”,打开开发者模式

一步一步导出证书

然后在打开sha256校验网址:http://www.atool.org/file_hash.php

或http://tools.jb51.net/password/sha_encode

这样就获取到了证书的sha256的值,写了一个工具类

/** * SSL证书错误,手动校验https证书 * * @param cert https证书 * @param sha256Str sha256值 * @return true通过,false失败 */ public static boolean isSSLCertOk(SslCertificate cert, String sha256Str) { byte[] SSLSHA256 = hexToBytes(sha256Str); Bundle bundle = SslCertificate.saveState(cert); if (bundle != null) { byte[] bytes = bundle.getByteArray("x509-certificate"); if (bytes != null) { try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); Certificate ca = cf.generateCertificate(new ByteArrayInputStream(bytes)); MessageDigest sha256 = MessageDigest.getInstance("SHA-256"); byte[] key = sha256.digest(((X509Certificate) ca).getEncoded()); return Arrays.equals(key, SSLSHA256); } catch (Exception e) { e.printStackTrace(); } } } return false; } /** * hexString转byteArr * <p>例如:</p> * hexString2Bytes("00A8") returns { 0, (byte) 0xA8 } * * @param hexString * @return 字节数组 */ public static byte[] hexToBytes(String hexString) { if (hexString == null || hexString.trim().length() == 0) return null; int length = hexString.length() / 2; char[] hexChars = hexString.toCharArray(); byte[] bytes = new byte[length]; String hexDigits = "0123456789abcdef"; for (int i = 0; i < length; i++) { int pos = i * 2; // 两个字符对应一个byte int h = hexDigits.indexOf(hexChars[pos]) << 4; // 注1 int l = hexDigits.indexOf(hexChars[pos + 1]); // 注2 if (h == -1 || l == -1) { // 非16进制字符 return null; } bytes[i] = (byte) (h | l); } return bytes; }

然后在onReceivedSslError()判断

webView.setWebViewClient(new WebViewClient() { @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { super.onReceivedSslError(view, handler, error); if (error.getPrimaryError() == SslError.SSL_INVALID) { // 如果手动校验sha256成功就允许加载页面 if (SSLCertUtil.isSSLCertOk(error.getCertificate(), "6683c9584b8287ec3a50e312f4a540c79938aaeb76bd02e40a9ca037ee5d24f4")) { handler.proceed(); } else { try { new AlertDialog.Builder(MainActivity.this) .setTitle("警告") .setMessage("证书校验失败") .setPositiveButton("退出", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { System.exit(0); dialog.dismiss(); } }).show(); } catch (Exception e) { e.printStackTrace(); } } } else { handler.cancel(); } } });

这里我们只是真对SslError.SSL_INVALID进行了判断,可能还有其他情况,根据自己的情况判定。

/** * The certificate is not yet valid */ public static final int SSL_NOTYETVALID = 0; /** * The certificate has expired */ public static final int SSL_EXPIRED = 1; /** * Hostname mismatch */ public static final int SSL_IDMISMATCH = 2; /** * The certificate authority is not trusted */ public static final int SSL_UNTRUSTED = 3; /** * The date of the certificate is invalid */ public static final int SSL_DATE_INVALID = 4; /** * A generic error occurred */ public static final int SSL_INVALID = 5;

这样就完成了手动校验https证书校

时间: 2024-09-20 08:39:06

Android webview手动校验https证书(by 星空武哥)的相关文章

微信Android热更新Tinker使用详解(星空武哥)

Tinker是什么 Tinker是微信官方的Android热补丁解决方案,它支持动态下发代码.So库以及资源,让应用能够在不需要重新安装的情况下实现更新.当然,你也可以使用Tinker来更新你的插件. 它主要包括以下几个部分: gradle编译插件: tinker-patch-gradle-plugin 核心sdk库: tinker-android-lib 非gradle编译用户的命令行版本: tinker-patch-cli.jar 为什么使用Tinker 当前市面的热补丁方案有很多,其中比较

AndroidStudio安全管理签名文件keystroe和签名密码(星空武哥)

AndroidStudio由于使用了gradle的进行项目构建,使我们开发app方便很多,今天我就给大家列出几点是用gradle的方便之处. 一.AndroidStudio Gradle第三依赖统一管理 二.AndroidStudio Gradle基于友盟的多渠道打包 三.AndroidStudio安全管理签名文件keystroe和签名密码 我们在使用AndroidStudio进行release版的apk签名的时候,往往都是将签名文件keystore放在项目中,密码写在build.gradle中

Android APP之WebView校验SSL证书的方法

Android系统的碎片化很严重,并且手机日期不正确.手机根证书异常.com.google.android.webview BUG等各种原因,都会导致WebViewClient无法访问HTTPS站点.SSL错误的处理方式十分关键,如果处理不当,可能导致中间人攻击,黑客窃听数据,进而引发安全事故. 严谨地处理onReceivedSslError尤为重要.请参考以下代码,原理是:如果webview报告SSL错误,程序将会对服务器证书进行强校验,如果服务器传入证书的指纹(sha256)与记录值一致,说

我的Android进阶之旅------&amp;gt;Android关于HttpsURLConnection一个忽略Https证书是否正确的Https请求工具类

       下面是一个Android HttpsURLConnection忽略Https证书是否正确的Https请求工具类,不需要验证服务器端证书是否正确,也不需要验证服务器证书中的域名是否有效.        (PS:建议下面代码仅仅用于测试阶段,不建议用于发布后的产品中.否则的话HTTPS就形同虚设了.) import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import

android webview https网页中的http图片加载不出来

问题描述 android webview https网页中的http图片加载不出来 RT,在项目中用webview加载一个https开头的网页,网页加载出来了,但网页里http开头的图片在android 4.4的手机上能加载出来,在android5.0.1 的手机上就加载不出来. android 5.0.1:The page at 'https://api.app-test.cn/activity/view?id=25' was loaded over HTTPS but displayed i

Android 安全加密:Https编程详解_Android

Android安全加密专题文章索引 Android安全加密:对称加密 Android安全加密:非对称加密 Android安全加密:消息摘要Message Digest Android安全加密:数字签名和数字证书 Android安全加密:Https编程 以上学习所有内容,对称加密.非对称加密.消息摘要.数字签名等知识都是为了理解数字证书工作原理而作为一个预备知识.数字证书是密码学里的终极武器,是人类几千年历史总结的智慧的结晶,只有在明白了数字证书工作原理后,才能理解Https 协议的安全通讯机制.

Android 安全加密:Https编程详解

Android安全加密专题文章索引 Android安全加密:对称加密 Android安全加密:非对称加密 Android安全加密:消息摘要Message Digest Android安全加密:数字签名和数字证书 Android安全加密:Https编程 以上学习所有内容,对称加密.非对称加密.消息摘要.数字签名等知识都是为了理解数字证书工作原理而作为一个预备知识.数字证书是密码学里的终极武器,是人类几千年历史总结的智慧的结晶,只有在明白了数字证书工作原理后,才能理解Https 协议的安全通讯机制.

android webview点击链接不及时显示

问题描述 android webview点击链接不及时显示 点击html界面的一个链接,使用js的方法改变某个div标签的内容,但无法及时显示,要多次点击,或退出后在进入点击才能显示出来,我手动刷新界面或清除缓存也没法做到点击后及时显示改变内容 解决方案 你换一个别的浏览器客户端试试看呢 解决方案二: 你用的android版本是哪个 据网友反应,在Android4.4以上不支持js的一些方法了,可以参考这个开源项目:https://github.com/lzyzsd/JsBridge 解决方案三

Android Webview中Vue初始化的性能优化

前言 一般来说,你不需要太关心vue的运行时性能,它在运行时非常快,但付出的代价是初始化时相对较慢.在最近开发的一个Hybrid APP里,Android Webview初始化一个较重的vue页面竟然用了1200ms ~ 1400ms,这让我开始重视vue的初始化性能,并最终优化到200 ~ 300ms,这篇文章分享我的优化思路. 性能瓶颈在哪里? 先看一下常见的vue写法:在html里放一个app组件,app组件里又引用了其他的子组件,形成一棵以app为根节点的组件树. <body>