有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java“PKIX路径构建失败”和“无法找到请求目标的有效证书路径”

我正在尝试使用twitter4j库为我的java项目获取推文,该项目使用UndertheCoversjava.net.HttpURLConnection(如StackTrace中所示)。在第一次运行时,我得到一个关于证书sun.security.validator.ValidatorExceptionsun.security.provider.certpath.SunCertPathBuilderException的错误。然后,我通过以下方式添加了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"

但是没有成功。以下是获取推文的过程:

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());
    }

下面是错误:

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

共 (6) 个答案

  1. # 1 楼答案

    1. 转到浏览器中的URL:
    • firefox-单击HTTPS证书链(URL地址旁边的锁定图标)。单击"more info" > "security" > "show certificate" > "details" > "export.."。选择名称并选择文件类型示例。cer
    • chrome-单击左侧的站点图标以在地址栏中找到地址,选择“证书”->;“详情”->;“导出”并以“Der编码二进制,单证书”格式保存
    1. 现在您有了带有密钥库的文件,您必须将其添加到JVM中。确定cacerts文件的位置,例如。 C:\Program Files (x86)\Java\jre1.6.0_22\lib\security\cacerts.

    2. 接下来将example.cer文件导入命令行中的cacerts(可能需要管理员命令提示):

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

    您将被要求输入默认为changeit的密码

    重新启动JVM/PC

    资料来源: http://magicmonster.com/kb/prg/java/ssl/pkix_path_building_failed.html

  2. # 2 楼答案

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

    它用于跳转证书验证

    警告 仅用于开发目的,因为这是不安全的

  3. # 3 楼答案

    我的UI方法:

    1. here下载密钥库资源管理器
    2. 打开$JAVA_HOME/jre/lib/security/cacerts
    3. 输入PW:changeit(可以是Mac上的changeme)
    4. 导入您的。crt文件

    命令行:

    1. keytool -importcert -file jetty.crt -alias jetty -keystore $JAVA_HOME/jre/lib/security/cacerts
    2. 输入PW:changeit(可以是Mac上的changeme)
  4. # 4 楼答案

    一,。检查证书

    尝试在浏览器中加载目标URL并查看站点的证书(通常可以通过带有锁定标志的图标访问。它位于浏览器地址栏的左侧或右侧),无论该证书是否已过期或因其他原因不受信任

    二,。安装最新版本的JRE和JDK

    新版本通常附带一组更新的可信证书

    如果可能的话,卸载旧版本。这将明确错误配置错误

    三,。检查您的配置:

    • 检查JAVA_HOME环境变量指向的位置
    • 检查用于运行程序的java版本。在IntelliJ检查中:
      • 文件->;项目结构-&燃气轮机;项目设置->;项目->;Project SDK:
      • 文件->;项目结构-&燃气轮机;平台设置->;SDK

    四,。从新Java版本复制整个密钥库

    如果您在JDK下开发的不是最新的可用文件,请尝试用最新安装的JRE中的新文件替换%JAVA_HOME%/jre/lib/security/cacerts文件(首先制作备份副本),正如@jeremy goodell在他的answer中所建议的那样

    五,。将证书添加到密钥库

    如果上面的任何内容都不能解决您的问题,请使用keytool将证书保存到Java的密钥库:

    keytool -trustcacerts -keystore "%JAVA_HOME%jre\lib\security\cacerts" -storepass changeit -importcert -alias <alias_name> -file <path_to_crt_file>
    

    如@maggg在他的answer中建议的那样,可以从浏览器中获取带有证书的文件

    注1:您可能需要对站点证书链中的每个证书重复此操作。从根开始

    注2:<alias_name>在存储区中的键之间应该是唯一的,否则keytool将显示错误

    要获取存储区中所有证书的列表,您可以运行:

    keytool -list -trustcacerts -keystore "%JAVA_HOME%jre\lib\security\cacerts" -storepass changeit
    

    如果出现问题,这将帮助您从存储中删除证书:

    keytool -delete -alias <alias_name> -keystore "%JAVA_HOME%jre\lib\security\cacerts" -storepass changeit
    
  5. # 5 楼答案

    为了让我的Java 6安装能够使用新的twitter证书,我花了好几个小时试图构建证书文件,最后我在一个留言板的评论中偶然发现了一个非常简单的解决方案。只需从Java7安装中复制cacerts文件,并覆盖Java6安装中的文件。也许最好先备份cacerts文件,但你只需将新文件复制进来,就可以了!它只是工作

    请注意,我实际上是将一个WindowsCacerts文件复制到Linux安装中的,它工作得很好

    在旧的和新的JavaJDK安装中,该文件都位于jre/lib/security/cacerts

    希望这能帮别人省下几个小时的烦恼

  6. # 6 楼答案

    我偶然发现这个问题,花了很多小时的研究来解决,特别是自动生成的证书,与官方证书不同,它非常棘手,Java不太喜欢它们

    请检查以下链接:Solve Problem with certificates in Java

    基本上,您必须将服务器上的证书添加到Java主证书中

    1. 生成或获取您的证书,并将Tomcat配置为在服务器中使用它。xml
    2. 下载类InstallCert的Java源代码,并在服务器运行时执行它,提供以下参数server[:port]。不需要密码,因为原始密码适用于Java证书(“changeit”)
    3. 程序将连接到服务器,Java将抛出一个异常,它将分析服务器提供的证书,并允许您在执行程序的目录中创建一个jssecerts文件(如果从Eclipse执行,请确保在Run -> Configurations中配置工作目录)
    4. 手动将该文件复制到$JAVA_HOME/jre/lib/security

    遵循这些步骤后,与证书的连接将不再在Java中生成异常

    下面的源代码很重要,它从(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);
            }
        }
    }