![](/img/trans.png)
[英]PKIX path building failed sun.security.provider.certpath.SunCertPathBuilderException
[英]How to ignore PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException?
嘗試向 http 服務器發送請求時出現以下異常:
這是我使用的代碼
URL url = new URL(
"https://www.abc.com");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
// wr.writeBytes(params);
wr.flush();
wr.close();
BufferedReader br = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
這是例外:
Exception in thread "main" 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 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1731)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:925)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1170)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1197)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1181)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1014)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
at com.amazon.mzang.tools.httpchecker.CategoryYank.getPV(CategoryYank.java:32)
at com.amazon.mzang.tools.httpchecker.CategoryYank.main(CategoryYank.java:18)
Caused by: 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.validator.PKIXValidator.doBuild(PKIXValidator.java:323)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217)
at sun.security.validator.Validator.validate(Validator.java:218)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185)
... 13 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318)
... 19 more
服務器不歸我所有。 有沒有辦法忽略這個異常?
我使用下面的代碼覆蓋我項目中的 SSL 檢查,它對我有用。
package com.beingjavaguys.testftp;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
/**
* Fix for Exception in thread "main" 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
*/
public class ConnectToHttpsUrl {
public static void main(String[] args) throws Exception {
/* Start of Fix */
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; }
public void checkClientTrusted(X509Certificate[] certs, String authType) { }
public void checkServerTrusted(X509Certificate[] certs, String authType) { }
} };
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) { return true; }
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
/* End of the fix*/
URL url = new URL("https://nameofthesecuredurl.com");
URLConnection con = url.openConnection();
Reader reader = new InputStreamReader(con.getInputStream());
while (true) {
int ch = reader.read();
if (ch == -1)
break;
System.out.print((char) ch);
}
}
}
如果您想一起忽略證書,請查看此處的答案: Ignore self-signed ssl cert using Jersey Client
盡管這會使您的應用容易受到中間人攻擊。
或者,嘗試將證書作為受信任的證書添加到您的 Java 商店。 這個網站可能會有幫助。 http://blog.icodejava.com/tag/get-public-key-of-ssl-certificate-in-java/
這是另一個顯示如何向您的商店添加證書的線程。 Java SSL連接,以編程方式將服務器證書添加到密鑰庫
關鍵是:
KeyStore.Entry newEntry = new KeyStore.TrustedCertificateEntry(someCert);
ks.setEntry("someAlias", newEntry, null);
將JSoup命令的validateTLSCertificates
屬性設置為false
。
Jsoup.connect("https://google.com/").validateTLSCertificates(false).get();
如果問題是缺少中間證書,您可以啟用 Oracle JRE 以自動下載丟失的中間證書,如本答案中所述。
只需設置 Java 系統屬性-Dcom.sun.security.enableAIAcaIssuers=true
為此,服務器的證書必須向中間證書(證書的頒發者)提供 URI。 據我所知,這也是瀏覽器所做的,並且應該同樣安全——盡管我不是安全專家。
編輯:如果我沒記錯的話,這似乎至少適用於 Java 8 並且在此處記錄了 Java 9 。
FWIW,在 Ubuntu 10.04.2 LTS 上安裝 ca-certificates-java 和 ca-certificates 包為我解決了這個問題。
我在執行下面的 spring-boot + RestAssured 簡單測試時遇到了同樣的錯誤。
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static com.jayway.restassured.RestAssured.when;
import static org.apache.http.HttpStatus.SC_OK;
@RunWith(SpringJUnit4ClassRunner.class)
public class GeneratorTest {
@Test
public void generatorEndPoint() {
when().get("https://bal-bla-bla-bla.com/generators")
.then().statusCode(SC_OK);
}
}
在我的案例中,簡單的解決方法是添加“useRelaxedHTTPSValidations()”
RestAssured.useRelaxedHTTPSValidation();
然后測試看起來像
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static com.jayway.restassured.RestAssured.when;
import static org.apache.http.HttpStatus.SC_OK;
@RunWith(SpringJUnit4ClassRunner.class)
public class GeneratorTest {
@Before
public void setUp() {
RestAssured.useRelaxedHTTPSValidation();
}
@Test
public void generatorEndPoint() {
when().get("https://bal-bla-bla-bla.com/generators")
.then().statusCode(SC_OK);
}
}
如果您使用的是 CloudFoundry,那么您必須顯式推送 jar 以及具有證書的密鑰庫。
我也面臨這個問題。 我有JDK 1.8.0_121
。 我將 JDK 升級到1.8.0_181
,它運行得非常棒。
我也遇到了同樣的問題。 我試圖以clean install
目標構建項目。 我只是在運行配置中將其更改為clean package -o
。 然后我重新構建了這個項目,它對我有用。
我在 Apache Tomcat/7.0.67 和 Java JVM 版本:1.8.0_66-b18 上也有同樣的問題。 剛剛升級到 JRE 1.8.0_241 似乎問題就解決了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.