https://我在使用OkHttp 会报unable to find valid certification path to requested target错误
javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alert.createSSLException(Alert.java:131) ~[?:?]
at sun.security.ssl.TransportContext.fatal(TransportContext.java:321) ~[?:?]
at sun.security.ssl.TransportContext.fatal(TransportContext.java:264) ~[?:?]
at sun.security.ssl.TransportContext.fatal(TransportContext.java:259) ~[?:?]
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:646) ~[?:?]
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:465) ~[?:?]
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:361) ~[?:?]
at sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392) ~[?:?]
at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:450) ~[?:?]
at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:427) ~[?:?]
at sun.security.ssl.TransportContext.dispatch(TransportContext.java:178) ~[?:?]
at sun.security.ssl.SSLTransport.decode(SSLTransport.java:164) ~[?:?]
简单翻译下,“无法找到请求目标的有效认证路径”,一般情况下是你使用请求是带有:
https://
由于https需要证书校验,所有报以上错误,如果没有需要校验可以忽略https证书校验。
我使用的是okhttp 的url 请求工具,其他类型请自行网上查找;
创建一个SSLSocketClientUtil公共类
import javax.net.ssl.*;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
/**
* @author wcy
* @date 2020/3/4
* 为了支持okhttp 绕过验签功能
**/
public class SSLSocketClientUtil {
public static SSLSocketFactory getSocketFactory(TrustManager manager) {
SSLSocketFactory socketFactory = null;
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]{manager}, new SecureRandom());
socketFactory = sslContext.getSocketFactory();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return socketFactory;
}
public static X509TrustManager getX509TrustManager() {
return new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
}
public static HostnameVerifier getHostnameVerifier() {
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
};
return hostnameVerifier;
}
}
配置okhttp 在创建okhttpClient的时候添加两个拦截器sslSocketFactory和hostnameVerifier
static {
// 支持https请求,绕过验证
X509TrustManager manager = SSLSocketClientUtil.getX509TrustManager();
httpClient = new OkHttpClient.Builder()
.connectTimeout(CINNETC_TIMEOUT, TimeUnit.MILLISECONDS)
.readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
.sslSocketFactory(SSLSocketClientUtil.getSocketFactory(manager), manager)// 忽略校验
.hostnameVerifier(SSLSocketClientUtil.getHostnameVerifier())//忽略校验
.connectionPool(new ConnectionPool(MAX_IDLE_CONNECTION, KEEP_ALIVE_DURATION, TimeUnit.MINUTES))
.build();
}