2020年9月23日 星期三

[java]使用okhttp3時發生SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

at sun.security.ssl.Alerts.getSSLException(Unknown Source)

at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)

at sun.security.ssl.Handshaker.fatalSE(Unknown Source)

at sun.security.ssl.Handshaker.fatalSE(Unknown Source)

at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)

at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)

at sun.security.ssl.Handshaker.processLoop(Unknown Source)

at sun.security.ssl.Handshaker.process_record(Unknown Source)

at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)

at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)

at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)

at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)

at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:268)

at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:238)

at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:149)

at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:192)

at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121)

at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100)

at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)

at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)

at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)

at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)

at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)

at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)

at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)

at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)

at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)

at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)

at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)

at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185)

at okhttp3.RealCall.execute(RealCall.java:69)


 

解法

new OkHttpClient();改成getUnsafeOkHttpClient();

import javax.net.ssl.HostnameVerifier;

import javax.net.ssl.SSLContext;

import javax.net.ssl.SSLSession;

import javax.net.ssl.TrustManager;

import javax.net.ssl.X509TrustManager;


/**

* okHttp3信任所有證書

* @return OkHttpClient

*/

public static OkHttpClient getUnsafeOkHttpClient() {

try {

final TrustManager[] trustAllCerts = new TrustManager[]{

new X509TrustManager() {

@Override

public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {

}

@Override

public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {

}

@Override

public java.security.cert.X509Certificate[] getAcceptedIssuers() {

return new java.security.cert.X509Certificate[]{};

}

}

};

final SSLContext sslContext = SSLContext.getInstance("SSL");

sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

final javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

OkHttpClient.Builder builder = new OkHttpClient.Builder();

builder.sslSocketFactory(sslSocketFactory);


builder.hostnameVerifier(new HostnameVerifier() {

@Override

public boolean verify(String hostname, SSLSession session) {

return true;

}

});

return builder.build();

} catch (Exception e) {

throw new RuntimeException(e);

}

}






^