一、最好的方式是后端给一个.crt或者.pem 证书文件放入res/raw目录下解决所有问题
在应用的AndroidManifest.xml中声明一个自定义的 CA 证书存储目录
例如:
<application
android:networkSecurityConfig="@xml/network_config"
<!-- 其他配置 -->
</application>
res/xml目录下network_config文件
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="@raw/my_certificate"/>
</trust-anchors>
</base-config>
</network-security-config>
二、获取网络图片或文件出现SSLHandshakeException
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
接入阿里云OSS获取图片后出现CertPathValidatorException,解决方式如下
Application中初始化
@Override
public void onCreate() {
super.onCreate();
//忽略https的证书校验
handleSSLHandshake();
//Glide加载异常
Glide.get(this).getRegistry().replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(getNoCheckOkHttpClient()));
}
/**
* 忽略https的证书校验
* javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
*/
private void handleSSLHandshake() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{getTrustManager()};
SSLContext sc = SSLContext.getInstance("TLS");
//trustAllCerts信任所有的证书
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 避免Glide加载https图片报错:
* @return
*/
private OkHttpClient getNoCheckOkHttpClient() {
SSLSocketFactory ssl = getNoCheckSSLSocketFactory();
X509TrustManager trustManager = getTrustManager();
return new OkHttpClient.Builder()
.connectTimeout(TimeUnit.SECONDS.toMillis(30), TimeUnit.SECONDS)
.readTimeout(TimeUnit.SECONDS.toMillis(30), TimeUnit.SECONDS)
.writeTimeout(TimeUnit.SECONDS.toMillis(30), TimeUnit.SECONDS)
.sslSocketFactory(ssl, trustManager)
.hostnameVerifier((hostname, session) -> true)
.retryOnConnectionFailure(true)
.build();
}
private SSLSocketFactory getNoCheckSSLSocketFactory() {
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]{getTrustManager()}, new SecureRandom());
return sslContext.getSocketFactory();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 获得信任管理器TrustManager,不做任何校验
*
* @return X509TrustManager
*/
private X509TrustManager getTrustManager() {
return new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] serverX509Certificates, String s) {
}
/**
* 只支持正序或者逆序存放的证书链,如果证书链顺序打乱的将不支持 我们以下认定x509Certificates数组里从0-end如果是设备证书到ca root证书是正序的
* 反之是倒序的
*/
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
}