簡體   English   中英

如何忽略 PKIX 路徑構建失敗: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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM