// 完整的錯誤訊息
javax.net.ssl.SSLHandshakeException: PKIX 路徑建立失敗: sun.security.provider.certpath.SunCertPathBuilderException: 無法找到有效的憑證路徑到所請求的目標
這個錯誤意味著在 SSL/TLS 握手過程中,客戶端無法驗證伺服器的 SSL 憑證。原因有:
- 伺服器憑證不被客戶端信任:伺服器的 SSL 憑證可能未被客戶端信任的憑證頒發機構(CA)簽發,或者憑證已過期。
- 網路問題:在某些情況下,如果客戶端和伺服器之間的網路連線存在問題,也可能導致 SSL 握手失敗。
憑證方面解決#
那就是在服務端解決了,但是一般我們都是呼叫別人的介面,對方的 SSL 憑證有問題,我們也不能幫別人修改對吧
自己解決#
自己解決那就是忽略 SSL 憑證驗證,但這會降低安全性,不建議使用,除非迫不得已
// 創建一個無需驗證 SSL 的 OkHttpClient
public static OkHttpClient getClient() throws NoSuchAlgorithmException, KeyManagementException {
TrustManager[] trustManagers = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
};
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagers, new SecureRandom());
final OkHttpClient client = new OkHttpClient.Builder()
.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustManagers[0])
.hostnameVerifier((s, sslSession) -> true)
.build();
return client;
}
private final OkHttpClient client = getClient();
// 現在忽略 SSL 憑證驗證的 OKHttpClient 對象就有了