HTTPS,证书有效期与手机时间不符合时,如何让验证通过

情景:公司购买了三年verisign的证书使用期,但是手机本地时间如果设为这三年以外的,会发生证书过期CertificateExpiredException或者证书尚未生效CertificateNotYetValidException的异常,这样基于https的网络交互都将无法进行下去,还需要提醒用户取更改手机时间,再回来进行网络操作,影响到用户体验。


目的:对于证书有效期引起的这两个异常,让验证通过(trust),其他原因引起的异常,按正常的逻辑处理。


方案如下:

HttpURLConnection conn;
if (baseUrl.startsWith("https")) {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[] {
new MyTrustManager()
}, new SecureRandom());
HttpsURLConnection
.setDefaultSSLSocketFactory(sc.getSocketFactory());
conn = (HttpsURLConnection) new URL(baseUrl)
.openConnection();
} else {
conn = (HttpURLConnection) new URL(baseUrl).openConnection();
}




class MyTrustManager implements X509TrustManager {
private X509TrustManager tm = null;

MyTrustManager() {
try {
//以下几步是关键,通过分析源码和异常栈而来。

KeyStore keyStore = KeyStore.getInstance("AndroidCAStore");
keyStore.load(null, null);
tm = new TrustManagerImpl(keyStore);
} catch (Exception e) {
e.printStackTrace();
}
}

@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
tm.checkClientTrusted(chain, authType);
}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
try {
tm.checkServerTrusted(chain, authType);
} catch (CertificateException e) {
e.printStackTrace();
Throwable t = e;
while (t != null) {
if (t instanceof CertificateExpiredException
|| t instanceof CertificateNotYetValidException)
return;
t = t.getCause();
}
throw e;
}
}

@Override
public X509Certificate[] getAcceptedIssuers() {
return tm.getAcceptedIssuers();
}

}


你可能感兴趣的:(HTTPS,证书有效期与手机时间不符合时,如何让验证通过)