有些时候由于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./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证书校
# webview手动校验https证书
# Android okhttp3.0忽略https证书的方法
# Android Https证书过期的两种解决方案
# 加载
# 自己的
# 都是
# 华为
# 就会
# 很多人
# 其他的
# 也可
# 这也
# 就没
# 写了
# 升级到
# 按下
# 打不开
# 解决这个问题
# 进行了
# 失去了
# 情况下
# 这时候
# 完成了
相关文章:
如何彻底卸载建站之星软件?
简单实现Android验证码
定制建站模板如何实现SEO优化与智能系统配置?18字教程
如何设置并定期更换建站之星安全管理员密码?
php8.4新语法match怎么用_php8.4match表达式替代switch【方法】
官网自助建站系统:SEO优化+多语言支持,快速搭建专业网站
如何设计高效校园网站?
外汇网站制作流程,如何在工商银行网站上做外汇买卖?
如何在宝塔面板中修改默认建站目录?
公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?
如何快速上传建站程序避免常见错误?
如何用西部建站助手快速创建专业网站?
高性能网站服务器配置指南:安全稳定与高效建站核心方案
较简单的网站制作软件有哪些,手机版网页制作用什么软件?
音乐网站服务器如何优化API响应速度?
c# 在高并发场景下,委托和接口调用的性能对比
如何在万网主机上快速搭建网站?
b2c电商网站制作流程,b2c水平综合的电商平台?
XML的“混合内容”是什么 怎么用DTD或XSD定义
如何在万网自助建站中设置域名及备案?
如何选购建站域名与空间?自助平台全解析
建站之星如何快速解决建站难题?
制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?
焦点电影公司作品,电影焦点结局是什么?
建站主机数据库如何配置才能提升网站性能?
建站主机选购指南与交易推荐:核心配置解析
制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?
浅析上传头像示例及其注意事项
企业宣传片制作网站有哪些,传媒公司怎么找企业宣传片项目?
青岛网站设计制作公司,查询青岛招聘信息的网站有哪些?
如何通过西部数码建站助手快速创建专业网站?
如何快速使用云服务器搭建个人网站?
婚礼视频制作网站,学习*后期制作的网站有哪些?
网站制作需要会哪些技术,建立一个网站要花费多少?
在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?
如何选择适配移动端的WAP自助建站平台?
山东网站制作公司有哪些,山东大源集团官网?
如何在阿里云虚拟主机上快速搭建个人网站?
建站主机核心功能解析:服务器选择与网站搭建流程指南
如何构建满足综合性能需求的优质建站方案?
如何在IIS中配置站点IP、端口及主机头?
如何在Windows环境下新建FTP站点并设置权限?
网站建设制作、微信公众号,公明人民医院怎么在网上预约?
如何通过网站建站时间优化SEO与用户体验?
如何在IIS中新建站点并配置端口与IP地址?
岳西云建站教程与模板下载_一站式快速建站系统操作指南
高配服务器限时抢购:企业级配置与回收服务一站式优惠方案
如何在万网ECS上快速搭建专属网站?
C++如何使用std::optional?(处理可选值)
建站VPS配置与SEO优化指南:关键词排名提升策略
*请认真填写需求信息,我们会在24小时内与您取得联系。