一、获取证书
在显示有安全标志的网页上,点击安全哪里,然后点击证书,如图所示:
或者按F12,如图所示:
最终都会到底下图所示页面:
然后按步骤一步一步进行:
但是选择证书的格式也是有区别的,此处使用的是base64的格式,如下图所示:
二、获取证书信息
下载好证书后,则打开证书,复制里面所有的信息,到https://www.myssl.cn/tools/downloadchain.html这个网址,进行证书分析:
如图所示:
至此,我们获取到了我们想要的证书信息:此处使用的是指纹sha256的java数组。
三、证书验证
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
//webView默认是不处理https请求的,页面显示空白,需要进行如下设置:
// handler.proceed(); //继续使用SSL证书。
// handler.cancel(); // 取消此请求以及出现错误的WebView的所有待处理请求。
// handler.handleMessage(null); //可做其他处理
if (error.getPrimaryError() == SslError.SSL_DATE_INVALID // 日期不正确
|| error.getPrimaryError() == SslError.SSL_EXPIRED // 日期不正确
|| error.getPrimaryError() == SslError.SSL_INVALID // webview BUG
|| error.getPrimaryError() == SslError.SSL_UNTRUSTED) { // 根证书丢失
if (chkMySSLCNCert(error.getCertificate())) {
handler.proceed(); // 如果证书一致,忽略错误
}
}
}
private boolean chkMySSLCNCert(SslCertificate cert) {
byte[] CrtSha256 = {-70, -83, -39, 63, -107, -10, 88, -99, -29, 84, -118, 124, -93, 41, 2, -53, -72, 49, -124, -94, -30, -36, 123, 74, 5, 116, 56, -127, 72, -43, -68, 59 }; //证书指纹
Bundle bundle = SslCertificate.saveState(cert);
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, CrtSha256);
} catch (Exception Ex) {
}
}
return false;
}
webview的onReceivedSslError()方法
SslErrorHandler方法:
缺陷:此方法虽然是可以验证证书,但是在证书过期后更新证书信息之后,相对的指纹sha256的信息也会改变,所以对app还是有影响。