retrofit2碰到的SSLHandshakeException

错误

在使用retrofit2请求正式https接口时报错:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for cert

原因

服务端https证书配置错误

解决方法

忽略证书检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
OkHttpClient okHttpClient = new OkHttpClient();
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
}

@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
}

@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
}}, new SecureRandom());
} catch (Exception e) {
e.printStackTrace();
}

HostnameVerifier verifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};

try {
Class className = Class.forName("okhttp3.OkHttpClient");
Field hostnameVerifier = className.getDeclaredField("hostnameVerifier");
hostnameVerifier.setAccessible(true);
hostnameVerifier.set(sClient, verifier);

Field sslSocketFactory = className.getDeclaredField("sslSocketFactory");
sslSocketFactory.setAccessible(true);
sslSocketFactory.set(sClient, sslContext.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}

new Retrofit.Builder()
.baseUrl("你的url")
//设置okHttpClient
.client(okHttpClient)
.build();

根本解决方法

上面的代码可以解决请求报错的问题,并且请求到数据,但是根本原因是服务端https证书配置错误,有可能是中间证书忘记配置,或者证书顺序不对(此时iOS,H5都是可以正常访问的,但是安卓比较严格),所以还是让服务端人员检查一下