“ PKIX路徑構建失敗”和“無法找到到所請求目標的有效認證路徑”

本文翻譯自:“PKIX path building failed” and “unable to find valid certification path to requested target”

I'm trying to get tweets using twitter4j library for my java project. 我正在嘗試爲我的Java項目使用twitter4j庫獲取推文。 On my first run I got an error about certificate sun.security.validator.ValidatorException and sun.security.provider.certpath.SunCertPathBuilderException . 第一次運行時,我收到有關證書sun.security.validator.ValidatorExceptionsun.security.provider.certpath.SunCertPathBuilderException的錯誤。 Then I added twitter certificate by: 然後我通過以下方式添加了Twitter證書:

C:\Program Files\Java\jdk1.7.0_45\jre\lib\security>keytool -importcert -trustcacerts -file PathToCert -alias ca_alias -keystore "C:\Program Files\Java\jdk1.7.0_45\jre\lib\security\cacerts"

But without success. 但是沒有成功。 Here is the procedure to get twitters: 這是獲取推特的過程:

public static void main(String[] args) throws TwitterException {
    ConfigurationBuilder cb = new ConfigurationBuilder();
    cb.setDebugEnabled(true)
        .setOAuthConsumerKey("myConsumerKey")
        .setOAuthConsumerSecret("myConsumerSecret")
        .setOAuthAccessToken("myAccessToken")
        .setOAuthAccessTokenSecret("myAccessTokenSecret");

    TwitterFactory tf = new TwitterFactory(cb.build());
    Twitter twitter = tf.getInstance();

    try {
        Query query = new Query("iphone");
        QueryResult result;
        result = twitter.search(query);
        System.out.println("Total amount of tweets: " + result.getTweets().size());
        List<Status> tweets = result.getTweets();

        for (Status tweet : tweets) {
            System.out.println("@" + tweet.getUser().getScreenName() + " : " + tweet.getText());
        }
    } catch (TwitterException te) {
        te.printStackTrace();
        System.out.println("Failed to search tweets: " + te.getMessage());
    }

And here is the error: 這是錯誤:

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Relevant discussions can be found on the Internet at:
    http://www.google.co.jp/search?q=d35baff5 or
    http://www.google.co.jp/search?q=1446302e
TwitterException{exceptionCode=[d35baff5-1446302e 43208640-747fd158 43208640-747fd158 43208640-747fd158], statusCode=-1, message=null, code=-1, retryAfter=-1, rateLimitStatus=null, version=3.0.5}
    at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:177)
    at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:61)
    at twitter4j.internal.http.HttpClientWrapper.get(HttpClientWrapper.java:81)
    at twitter4j.TwitterImpl.get(TwitterImpl.java:1929)
    at twitter4j.TwitterImpl.search(TwitterImpl.java:306)
    at jku.cc.servlets.TweetsAnalyzer.main(TweetsAnalyzer.java:38)
Caused by: 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 sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at java.net.HttpURLConnection.getResponseCode(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
    at twitter4j.internal.http.HttpResponseImpl.<init>(HttpResponseImpl.java:34)
    at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:141)
    ... 5 more
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(Unknown Source)
    at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
    at sun.security.validator.Validator.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
    ... 20 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)
    ... 26 more
Failed to search tweets: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

#1樓

參考:https://stackoom.com/question/1QQsN/PKIX路徑構建失敗-和-無法找到到所請求目標的有效認證路徑


#2樓

Here normally this kind of exception occurs when there is mismatch in the PATH of trusted certificate. 在這種情況下,當可信證書的路徑不匹配時,通常會發生這種異常。 Check the configuration or path where this server certificate is required for secured communication. 檢查安全通信需要此服務器證書的配置或路徑。


#3樓

After many hours trying to build cert files to get my Java 6 installation working with the new twitter cert's, I finally stumbled onto an incredibly simple solution buried in a comment in one of the message boards. 在嘗試構建證書文件以使我的Java 6安裝與新的twitter cert一起工作之後,我花了許多時間才終於偶然發現了一個非常簡單的解決方案,該解決方案掩埋在其中一個留言板上的註釋中。 Just copy the cacerts file from a Java 7 installation and overwrite the one in your Java 6 installation. 只需從Java 7安裝中複製cacerts文件,然後覆蓋Java 6安裝中的cacerts文件。 Probably best to make a backup of the cacerts file first, but then you just copy the new one in and BOOM! 最好是先備份cacerts文件,然後再將新文件複製到BOOM中! it just works. 它只是工作。

Note that I actually copied a Windows cacerts file onto a Linux installation and it worked just fine. 請注意,我實際上將Windows cacerts文件複製到Linux安裝中,並且工作正常。

The file is located in jre/lib/security/cacerts in both the old and new Java jdk installations. 該文件位於新舊Java jdk安裝中的jre/lib/security/cacerts中。

Hope this saves someone else hours of aggravation. 希望這可以節省別人的時間。


#4樓

I have stumbled upon this issue which took many hours of research to fix, specially with auto-generated certificates, which unlike Official ones, are quite tricky and Java does not like them that much. 我偶然發現了一個需要花費大量時間進行研究的問題,特別是使用自動生成的證書進行修復,與官方證書不同,該證書非常棘手,Java不太喜歡它們。

Please check the following link: Solve Problem with certificates in Java 請檢查以下鏈接: 解決Java證書問題

Basically you have to add the certificate from the server to the Java Home certs. 基本上,您必須將證書從服務器添加到Java Home證書。

  1. Generate or Get your certificate and configure Tomcat to use it in Servers.xml 生成或獲取您的證書,並將Tomcat配置爲在Servers.xml中使用它
  2. Download the Java source code of the class InstallCert and execute it while the server is running, providing the following arguments server[:port] . 下載類InstallCert的Java源代碼,並在服務器運行時執行它,並提供以下參數server[:port] No password is needed, as the original password works for the Java certs ("changeit"). 不需要密碼,因爲原始密碼適用於Java證書(“ changeit”)。
  3. The Program will connect to the server and Java will throw an exception, it will analyze the certificate provided by the server and allow you to create a jssecerts file inside the directory where you executed the Program (If executed from Eclipse then make sure you configure the Work directory in Run -> Configurations ). 本程序將連接到服務器,而Java將引發異常,它將分析服務器提供的證書,並允許您在執行本程序的目錄內創建jssecerts文件(如果從Eclipse執行,請確保配置了Run -> Configurations )中的工作目錄。
  4. Manually copy that file to $JAVA_HOME/jre/lib/security 手動將該文件複製到$JAVA_HOME/jre/lib/security

After following these steps, the connections with the certificate will not generate exceptions anymore within Java. 完成這些步驟後,與證書的連接將不再在Java中生成異常。

The following source code is important and it disappeared from (Sun) Oracle blogs, the only page I found it was on the link provided, therefore I am attaching it in the answer for any reference. 以下源代碼很重要,並且從(Sun)Oracle博客中消失了,我發現它的唯一頁面是在所提供的鏈接上,因此,請將其附加在答案中以供參考。

/*
 * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/**
 * Originally from:
 * http://blogs.sun.com/andreas/resource/InstallCert.java
 * Use:
 * java InstallCert hostname
 * Example:
 *% java InstallCert ecc.fedora.redhat.com
 */

import javax.net.ssl.*;
import java.io.*;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * Class used to add the server's certificate to the KeyStore
 * with your trusted certificates.
 */
public class InstallCert {

    public static void main(String[] args) throws Exception {
        String host;
        int port;
        char[] passphrase;
        if ((args.length == 1) || (args.length == 2)) {
            String[] c = args[0].split(":");
            host = c[0];
            port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
            String p = (args.length == 1) ? "changeit" : args[1];
            passphrase = p.toCharArray();
        } else {
            System.out.println("Usage: java InstallCert [:port] [passphrase]");
            return;
        }

        File file = new File("jssecacerts");
        if (file.isFile() == false) {
            char SEP = File.separatorChar;
            File dir = new File(System.getProperty("java.home") + SEP
                    + "lib" + SEP + "security");
            file = new File(dir, "jssecacerts");
            if (file.isFile() == false) {
                file = new File(dir, "cacerts");
            }
        }
        System.out.println("Loading KeyStore " + file + "...");
        InputStream in = new FileInputStream(file);
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(in, passphrase);
        in.close();

        SSLContext context = SSLContext.getInstance("TLS");
        TrustManagerFactory tmf =
                TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];
        SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
        context.init(null, new TrustManager[]{tm}, null);
        SSLSocketFactory factory = context.getSocketFactory();

        System.out.println("Opening connection to " + host + ":" + port + "...");
        SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
        socket.setSoTimeout(10000);
        try {
            System.out.println("Starting SSL handshake...");
            socket.startHandshake();
            socket.close();
            System.out.println();
            System.out.println("No errors, certificate is already trusted");
        } catch (SSLException e) {
            System.out.println();
            e.printStackTrace(System.out);
        }

        X509Certificate[] chain = tm.chain;
        if (chain == null) {
            System.out.println("Could not obtain server certificate chain");
            return;
        }

        BufferedReader reader =
                new BufferedReader(new InputStreamReader(System.in));

        System.out.println();
        System.out.println("Server sent " + chain.length + " certificate(s):");
        System.out.println();
        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        for (int i = 0; i < chain.length; i++) {
            X509Certificate cert = chain[i];
            System.out.println
                    (" " + (i + 1) + " Subject " + cert.getSubjectDN());
            System.out.println("   Issuer  " + cert.getIssuerDN());
            sha1.update(cert.getEncoded());
            System.out.println("   sha1    " + toHexString(sha1.digest()));
            md5.update(cert.getEncoded());
            System.out.println("   md5     " + toHexString(md5.digest()));
            System.out.println();
        }

        System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
        String line = reader.readLine().trim();
        int k;
        try {
            k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
        } catch (NumberFormatException e) {
            System.out.println("KeyStore not changed");
            return;
        }

        X509Certificate cert = chain[k];
        String alias = host + "-" + (k + 1);
        ks.setCertificateEntry(alias, cert);

        OutputStream out = new FileOutputStream("jssecacerts");
        ks.store(out, passphrase);
        out.close();

        System.out.println();
        System.out.println(cert);
        System.out.println();
        System.out.println
                ("Added certificate to keystore 'jssecacerts' using alias '"
                        + alias + "'");
    }

    private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();

    private static String toHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 3);
        for (int b : bytes) {
            b &= 0xff;
            sb.append(HEXDIGITS[b >> 4]);
            sb.append(HEXDIGITS[b & 15]);
            sb.append(' ');
        }
        return sb.toString();
    }

    private static class SavingTrustManager implements X509TrustManager {

        private final X509TrustManager tm;
        private X509Certificate[] chain;

        SavingTrustManager(X509TrustManager tm) {
            this.tm = tm;
        }

        public X509Certificate[] getAcceptedIssuers() {
            throw new UnsupportedOperationException();
        }

        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            throw new UnsupportedOperationException();
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            this.chain = chain;
            tm.checkServerTrusted(chain, authType);
        }
    }
}

#5樓

-Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true

它用於跳轉證書驗證。


#6樓

  1. Go to URL in your firefox browser, click on HTTPS certificate chain (next to URL address). 在firefox瀏覽器中轉到URL,單擊HTTPS證書鏈(URL地址旁邊)。 Click "more info" > "security" > "show certificate" > "details" > "export.." . 單擊"more info" > "security" > "show certificate" > "details" > "export.." Pickup the name and choose file type example.cer. 提取名稱,然後選擇文件類型example.cer。 Now you have file with keystore and you have to add it to your JVM 現在,您有了帶有密鑰庫的文件,並且必須將其添加到JVM中

  2. Determine location of cacerts files, eg. 確定cacerts文件的位置,例如。 C:\\Program Files (x86)\\Java\\jre1.6.0_22\\lib\\security\\cacerts.

  3. Next import the example.cer file into cacerts in command line: 接下來,在命令行中將example.cer文件導入到cacerts中:

keytool -import -alias example -keystore C:\\Program Files (x86)\\Java\\jre1.6.0_22\\lib\\security\\cacerts -file example.cer

You will be asked for password which default is changeit 系統將要求您輸入密碼,默認密碼爲changeit

Restart your JVM/PC. 重新啓動您的JVM / PC。

source: http://magicmonster.com/kb/prg/java/ssl/pkix_path_building_failed.html 來源: http//magicmonster.com/kb/prg/java/ssl/pkix_path_building_failed.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章