Xây dựng đường dẫn PKIX không thành công và không thể tìm thấy đường dẫn chứng nhận hợp lệ cho mục tiêu được yêu cầu


423

Tôi đang cố gắng để có được tweet bằng thư viện twitter4j cho dự án java của tôi. Trong lần chạy đầu tiên, tôi đã gặp lỗi về chứng chỉ sun.security.validator.ValidatorExceptionsun.security.provider.certpath.SunCertPathBuilderException. Sau đó, tôi đã thêm chứng chỉ twitter bằng cách:

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"

Nhưng không thành công. Đây là thủ tục để có được tweet:

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

Và đây là lỗi:

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
Xin chào Vui lòng kiểm tra URL bên dưới. Tôi chắc chắn những điều này sẽ giúp bạn. java-samples.com/showtutorial.php?tutorialid=210 confluence.atlassian.com/display/JIRAKB/ trên . Bạn phải thêm chứng chỉ ssl của mình vào chứng chỉ java Truststore (Đường dẫn: jre / lib / security / cacerts).
sus007

Vui lòng tham khảo câu trả lời này cho giải pháp cộng với xác nhận bạn đang đóng gói phần mềm của mình dưới dạng gói? nếu có thì sao chép hệ thống biểu mẫu tệp cacerts của bạn và thay thế tệp jre cacerts được đóng gói đó.
positivecrux

hãy thử stackoverflow.com/a/9210661/4741746 này có thể đây là câu trả lời của bạn
gosavi sushant

2
Tôi chỉ sử dụng mã java này và cho https đừng quên chỉ định cổng là 443. Mã Java tại github.com/escline/InstallCert/blob/master/InstallCert.java Nó sẽ lấy tệp CACERTS của bạn và sẽ thêm tất cả các cộng đó chứng chỉ hiện tại cho URL bạn cung cấp làm đầu vào. Trong trường hợp của tôi, tôi đã mã hóa các giá trị thành host = "mywebservice.uat.xyz.com"; cảng = 443; mật khẩu = "thay đổi" .toCharArray (); Sau đó, chương trình tạo ra một tệp mới gọi là "jssecacerts" sẽ có mọi thứ. Đổi tên này thành "cacerts" và sử dụng cái này. Bạn sẽ được thiết lập tất cả.
Reddymails

Câu trả lời:


574
  1. Truy cập URL trong trình duyệt của bạn:
    • firefox - nhấp vào chuỗi chứng chỉ HTTPS (biểu tượng khóa ngay bên cạnh địa chỉ URL). Nhấn vào đây "more info" > "security" > "show certificate" > "details" > "export..". Chọn tên và chọn loại tệp example.cer
    • chrome - nhấp vào biểu tượng trang web bên trái để đánh địa chỉ trên thanh địa chỉ, chọn "Chứng chỉ" -> "Chi tiết" -> "Xuất" và lưu ở định dạng "Nhị phân mã hóa, chứng chỉ đơn".
  2. Bây giờ bạn có tệp với kho khóa và bạn phải thêm nó vào JVM của mình. Xác định vị trí của các tập tin cacerts, ví dụ. C:\Program Files (x86)\Java\jre1.6.0_22\lib\security\cacerts.

  3. Tiếp theo nhập example.certệp vào cacerts trong dòng lệnh:

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

Bạn sẽ được hỏi mật khẩu mặc định là changeit

Khởi động lại JVM / PC của bạn.

nguồn: http://magicmonster.com/kb/prg/java/ssl/pkix_path_building_fails.html


27
Tôi đã phải đặt đường dẫn trong dấu ngoặc kép và lưu nó thành Base64 thay vì DER
Theodore K.

3
wow..its hoạt động như một phép thuật bằng cách trong chrome, bạn chỉ cần nhấp vào biểu tượng khóa trên thanh địa chỉ bên trái, và sau đó nhấp vào chi tiết cộng với không cần khởi động lại
vào

8
Lưu ý rằng các hướng dẫn nên được lặp lại cho tất cả các chứng chỉ trong chuỗi. Ngoài ra aliastên của chứng chỉ trong dòng lệnh phải là duy nhất.
Lu55

5
Nếu nhà của bạn là JDK, hãy đảm bảo chỉ định rằng jre nằm trong đó: keytool -import -alias example -keystore "C: \ Program Files \ Java \ jdk1.8.0_73 \ jre \ lib \ security \ cacerts" -file example.cer
Jack BeNimble

12
Đối với bất kỳ ai gặp lỗi "truy cập bị từ chối", hãy đảm bảo bạn đang chạy dấu nhắc lệnh với tư cách quản trị viên.
Walker Christie

81

Sau nhiều giờ cố gắng xây dựng các tệp chứng chỉ để cài đặt Java 6 của tôi hoạt động với chứng chỉ twitter mới, cuối cùng tôi cũng tình cờ tìm thấy một giải pháp cực kỳ đơn giản được chôn trong một nhận xét trong một trong các bảng thông báo. Chỉ cần sao chép tệp cacerts từ bản cài đặt Java 7 và ghi đè lên tệp trong bản cài đặt Java 6 của bạn. Có lẽ tốt nhất để tạo một bản sao lưu của tập tin cacerts trước, nhưng sau đó bạn chỉ cần sao chép tập tin mới vào và BÙM! nó chỉ hoạt động.

Lưu ý rằng tôi thực sự đã sao chép một tập tin Windows vào một bản cài đặt Linux và nó hoạt động rất tốt.

Tệp được đặt trong jre/lib/security/cacertscả bản cài đặt jdk Java cũ và mới.

Hy vọng điều này sẽ giúp người khác tiết kiệm được nhiều giờ.


4
Tôi đang cố gắng truy cập máy chủ ssl bằng chứng chỉ tự ký, đã thử thêm chứng chỉ bằng keytool, nhưng không có may mắn, có gợi ý nào không?
Oleg Belousov

1
Vui mừng nó đã làm việc .. Nhưng bạn có biết nguyên nhân gốc rễ là gì. điều gì đã khiến nó thất bại với java 6 certs .. và java 7 certs đã khắc phục vấn đề như thế nào
Vishwanath gowda k

Điều này đã làm điều đó, mặc dù tôi đã đi từ icedtea 1.6 đến oracle 1.7. :)
nperson325681

Cũng xem xét giải pháp này: stackoverflow.com/questions/33439905/ từ
Piohen

10
Đối với những người như tôi đôi khi bỏ lỡ điều hiển nhiên - hãy chắc chắn rằng bạn sẽ tham gia $JAVA_HOME/jre/libchứ không phải $JAVA_HOME/lib- tôi đã dành một chút thời gian để thiếu chi tiết đó.
Ryan Heathcote

35

Phương pháp UI của tôi:

  1. Tải về keystore explorer từ đây
  2. Mở $ JAVA_HOME / jre / lib / security / cacerts
  3. nhập PW: changeit (Có thể thay đổi trên Mac)
  4. Nhập tệp .crt của bạn

CMD-Line:

  1. keytool -importcert -file jetty.crt -alias jetty -keystore $JAVA_HOME/jre/lib/security/cacerts
  2. nhập PW: changeit(Có thể thay đổi trên Mac)

1
Trên mac, với CMD-Line, nên sử dụng sudo để chạy lệnh. # Sudo keytool -importcert -file jetty.crt -alias cầu cảng -keystore $ JAVA_HOME / jre / lib / security / cacerts
malajisi

1
Trên Windows, lệnh sẽ hoạt động:keytool -importcert -file dinardap_cert.cer –alias dinardap –keystore “%JAVA_HOME%/jre/lib/security/cacerts”
Patricio Bonilla

lấy file cert ở đâu? Tôi không thể biết URL nào sẽ được chuyển đến. cầu tàu.com ?
kraftydevil

Tôi đã nhận được chứng chỉ của mình bằng cách xuất nó từ trình duyệt web, hành động theo ngữ cảnh trên ổ khóa
rtbf

28

Tôi đã vấp phải vấn đề này, phải mất nhiều giờ nghiên cứu để khắc phục, đặc biệt là với các chứng chỉ được tạo tự động, không giống như các chứng chỉ Chính thức, khá phức tạp và Java không thích chúng nhiều như vậy.

Vui lòng kiểm tra liên kết sau: Giải quyết vấn đề với các chứng chỉ trong Java

Về cơ bản, bạn phải thêm chứng chỉ từ máy chủ vào certs Java Home.

  1. Tạo hoặc Nhận chứng chỉ của bạn và định cấu hình Tomcat để sử dụng nó trong Servers.xml
  2. Tải xuống mã nguồn Java của lớp InstallCertvà thực thi nó trong khi máy chủ đang chạy, cung cấp các đối số sau đây server[:port]. Không cần mật khẩu, vì mật khẩu ban đầu hoạt động cho các tiểu trình Java ("changeit").
  3. Chương trình sẽ kết nối với máy chủ và Java sẽ đưa ra một ngoại lệ, nó sẽ phân tích chứng chỉ do máy chủ cung cấp và cho phép bạn tạo một jssecertstệp bên trong thư mục nơi bạn đã thực thi Chương trình (Nếu được thực thi từ Eclipse thì hãy chắc chắn rằng bạn định cấu hình Công việc thư mục trong Run -> Configurations).
  4. Sao chép thủ công tệp đó vào $JAVA_HOME/jre/lib/security

Sau khi làm theo các bước này, các kết nối với chứng chỉ sẽ không tạo ra ngoại lệ nữa trong Java.

Mã nguồn sau đây rất quan trọng và nó đã biến mất khỏi các blog của Oracle (Sun), trang duy nhất tôi tìm thấy nó nằm trên liên kết được cung cấp, do đó tôi đính kèm nó trong câu trả lời cho bất kỳ tài liệu tham khảo nào.

/*
 * 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);
        }
    }
}

2
Lưu ý các tập tin được tạo là jssecacerts!
DeanDP

Tôi đã thử sử dụng giải pháp này cho Java 7 và 8. Trong khi chạy trên Java 7, tôi đã nhận được Protocol_version hoặc handshake_failure cho tất cả các url kho lưu trữ từ xa mà tôi đã thử. SandeepanNath:test sandeepan.nath$ java InstallCert repo1.maven.org:443 Loading KeyStore /Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home/jre/lib/security/cacerts... Opening connection to repo1.maven.org:443 ... Starting SSL handshake... javax.net.ssl.SSLException: Received fatal alert: protocol_version .. Could not obtain server certificate chain
Sandeepan Nath

20

1. Kiểm tra giấy chứng nhận

Hãy thử tải URL mục tiêu trong trình duyệt và xem chứng chỉ của trang web (thường là biểu tượng có thể truy cập bằng dấu hiệu khóa. Nó nằm ở bên trái hoặc bên phải của thanh địa chỉ của trình duyệt) cho dù đó là lý do hết hạn hoặc không đáng tin cậy.

2. Cài đặt các phiên bản mới nhất của JRE và JDK

Các phiên bản mới thường đi kèm với bộ cập nhật các chứng chỉ tin cậy.

Ngoài ra nếu có thể, hãy gỡ cài đặt các phiên bản cũ. Điều này sẽ làm cho lỗi cấu hình sai rõ ràng.

3. Kiểm tra cấu hình của bạn:

  • Kiểm tra nơi biến môi trường JAVA_HOME của bạn trỏ đến.
  • Kiểm tra phiên bản java nào bạn sử dụng để chạy chương trình. Trong IntelliJ kiểm tra:
    • Tệp -> Cấu trúc dự án ... -> Cài đặt dự án -> Dự án -> SDK dự án:
    • Tệp -> Cấu trúc dự án ... -> Cài đặt nền tảng -> SDK

4. Sao chép toàn bộ kho khóa từ phiên bản Java mới

Nếu bạn phát triển theo JDK khác với bản mới nhất hiện có - hãy thử thay thế %JAVA_HOME%/jre/lib/security/cacertstệp bằng tệp mới từ JRE được cài đặt mới nhất (tạo bản sao lưu trước) như @ jeremy-goodell gợi ý trong câu trả lời của anh ấy

5. Thêm (các) chứng chỉ vào kho khóa của bạn

Nếu không có gì ở trên giải quyết được vấn đề của bạn, hãy sử dụng keytoolđể lưu (các) chứng chỉ vào kho khóa của Java:

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

Có thể lấy tệp có chứng chỉ từ trình duyệt như @MagGGG gợi ý trong câu trả lời của anh ấy .

Lưu ý 1: bạn có thể cần lặp lại điều này cho mọi chứng chỉ trong chuỗi đối với chứng chỉ trang web của bạn. Bắt đầu từ gốc.

Lưu ý 2: <alias_name>phải là duy nhất trong số các khóa trong cửa hàng hoặc keytoolsẽ hiển thị lỗi.

Để có danh sách tất cả các chứng chỉ trong cửa hàng, bạn có thể chạy:

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

Trong trường hợp có sự cố, điều này sẽ giúp bạn xóa chứng chỉ khỏi cửa hàng:

keytool -delete -alias <alias_name> -keystore "%JAVA_HOME%jre\lib\security\cacerts" -storepass changeit

Với cách xây dựng tốt này, nó sẽ là câu trả lời được chấp nhận.
Egor Hans

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

Nó được sử dụng để nhảy xác nhận chứng chỉ.

Cảnh báo Chỉ sử dụng cho mục đích phát triển cho việc này là không an toàn!


4
Nó được sử dụng để nhảy xác nhận chứng chỉ
gorums

2
@gorums Làm thế nào để thiết lập nó trong Eclipse?
malajisi

6
KHÔNG làm điều này trừ khi bạn muốn mạo hiểm chạy mã độc tùy ý trên máy của mình. Bị hạ thấp vì nó có nguy cơ ảnh hưởng đến bất kỳ máy nào chạy nó.
Bryan

1
Chỉ vì nó 'hoạt động' không có nghĩa là nó an toàn, bạn đang đặt mọi người làm theo lời khuyên này có nguy cơ. Có downvote của tôi
Paradoxis

1
@AceKing Vấn đề là đó không phải là mã đáng tin cậy nếu bạn không xác thực chứng chỉ. Điều đó nói rằng, tôi nghĩ rằng đây vẫn là một câu trả lời hữu ích. Mọi người làm điều đó chỉ cần hiểu những rủi ro.
Michael Mior

12

Tôi đã có một tình huống hơi khác, khi cả JDK và JRE 1.8.0_112 đều có mặt trên hệ thống của tôi.

Tôi đã nhập chứng chỉ CA mới vào [JDK_FOLDER]\jre\lib\security\cacertsbằng cách sử dụng lệnh đã biết:

keytool -import -trustcacerts -keystore cacerts -alias <new_ca_alias> -file <path_to_ca_cert_file>

Tuy nhiên, tôi vẫn nhận được lỗi xây dựng đường dẫn PKIX tương tự .

Tôi đã thêm thông tin gỡ lỗi vào java CLI, bằng cách sử dụng java -Djavax.net.debug=all ... > debug.log. Trong tệp debug.log, dòng bắt đầu bằng trustStore là: thực sự được trỏ đến cửa hàng cacerts được tìm thấy trong [JRE_FOLDER]\lib\security\cacerts.

Trong trường hợp của tôi, giải pháp là sao chép tệp cacerts được sử dụng bởi JDK (đã thêm CA mới) qua tệp được sử dụng bởi JRE và đã khắc phục sự cố.


Tôi đã nhập trực tiếp các certs tôi cần vào JRE / lib / security / cacerts bằng keytool, nhưng nó không thay đổi gì đối với tôi :( vẫn nhận được lỗi tương tự, tôi cũng đã thêm chúng qua IDE hoặc thậm chí vào đường dẫn lớp và thêm Bean vào chỉ định vị trí kho khóa !! Thật điên rồ!
Alex

8

Vấn đề cơ bản:

Tôi đã gặp lỗi sau khi thử chạy mvn clean install trong dự án của mình và thông qua tùy chọn xây dựng và dọn dẹp Netbeans IDE. Sự cố này là do chứng chỉ không khả dụng khi chúng tôi tải xuống qua NET bean IDE / thông qua dấu nhắc lệnh, nhưng có thể tải xuống các tệp qua trình duyệt.

Lỗi :

Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Could not transfer artifact com.java.project:product:jar:1.0.32 from/to repo-local (https://url/local-repo): sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target  

Nghị quyết:

1. Tải xuống chứng chỉ của Url trong câu hỏi:

  • Khởi chạy IE bằng cách "chạy với tư cách quản trị viên" (nếu không, chúng tôi sẽ không thể tải xuống chứng chỉ)
  • Nhập url trong IE-> https: // url / local-repo (Trong trường hợp của tôi, url này có chứng chỉ không đáng tin cậy nhập mô tả hình ảnh ở đây.)
  • Tải xuống chứng chỉ bằng cách nhấp vào Lỗi chứng chỉ -> xem chứng chỉ
  • Chọn tab Chi tiết -> sao chép vào tệp -> tiếp theo -> chọn "nhị phân được mã hóa DER X.509 (.CER)
  • lưu chứng chỉ ở một số vị trí, ví dụ: c: /user/sheldon/desktop/product.cer
  • Chúc mừng! bạn đã tải thành công chứng chỉ cho trang web

2. Bây giờ cài đặt kho lưu trữ khóa để khắc phục sự cố.

  • Chạy lệnh keytool để nối kho khóa đã tải xuống vào tệp chứng chỉ hiện có.
  • Lệnh: Lệnh dưới đây trong thư mục bin của jdk (JAVA_HOME) .

C: \ Tệp chương trình \ Java \ jdk1.8.0_141 \ jre \ bin> keytool -importcert -file "C: /user/sheldon/desktop/product.cer" -alias sản phẩm -keystore "C: / Tệp chương trình / Java / jdk1.8.0_141 / jre / lib / security / cacerts ".

  • Bạn sẽ được nhắc nhập mật khẩu. Nhập mật khẩu kho khóa: nhập lại "thay đổi" cho "Tin cậy chứng chỉ này? [Không]:", nhập "có"

Lệnh / đầu ra dòng lệnh mẫu:

keytool -importcert -file "C:/Users/sheldon/Desktop/product.cer" -alias product -keystore "C:/Program iles/Java/jdk1.8.0_141/jre/lib/security/cacerts"
Enter keystore password:
Trust this certificate? [no]:  yes
Certificate was added to keystore
  • Contgrats! bây giờ bạn đã thoát khỏi lỗi "xây dựng đường dẫn PKIX: sun.security.provider.certpath.SunCertPathBuilderException" trong IDE Netbeans của bạn.

Xin chào, tôi đã làm theo tất cả các bước nhưng không có may mắn :(
ManishNegi

Bạn có bất kỳ chứng chỉ nào khác trong đường dẫn khác với cacerts không? nếu bạn có một số thứ khác, hãy thử thêm nó vào chứng chỉ đó
Barani r

Cảm ơn @Barani r, Đó là lỗi của tôi khi tôi thực hiện lệnh từ jre và sử dụng JDK trong nhật thực của mình
ManishNegi

Không thể tải xuống chứng chỉ nhưng sau đó, "chạy với tư cách quản trị viên", đã hoạt động tốt.
Một lập trình viên khác

8

Tôi muốn nhập chứng chỉ cho smtp.gmail.com

Chỉ có giải pháp làm việc cho tôi là 1. Nhập lệnh để xem chứng chỉ này

D: \ openssl \ bin \ openssl.exe s_client -connect smtp.gmail.com:465

  1. Sao chép và lưu các dòng giữa "----- BEGIN CHỨNG NHẬN -----" và "----- CHỨNG NHẬN KẾT THÚC -----" vào một tệp, gmail.cer

  2. Chạy

    keytool -import -alias smtp.gmail.com -keystore "% JAVA_HOME% / jre / lib / security / cacerts" -file C: \ Users \ Admin \ Desktop \ gmail.cer

  3. Nhập mật khẩu chageit

  4. Nhấp vào có để nhập chứng chỉ

  5. Khởi động lại java

Bây giờ chạy lệnh và bạn tốt để đi


Cảm ơn bạn! Điều đó đã cứu ngày của tôi. Đây là giải pháp thích hợp duy nhất trong trường hợp của tôi.
Andrew Gans

Cứu cả ngày của tôi nữa. Cảm ơn bạn.
Kris

6

Đây không phải là câu trả lời dành riêng cho Twitter, nhưng đây là câu hỏi xuất hiện khi bạn tìm kiếm lỗi này. Nếu hệ thống của bạn nhận được lỗi này khi kết nối với một trang web dường như có chứng chỉ hợp lệ khi được xem trong trình duyệt web , điều đó có thể có nghĩa là trang web đó có chuỗi chứng chỉ không đầy đủ .

Để biết tóm tắt ngắn gọn về vấn đề: Cơ quan cấp chứng chỉ không sử dụng Chứng chỉ gốc của họ để ký bất kỳ chứng chỉ cũ nào. Thay vào đó, họ (thường) ký các chứng chỉ trung gian cũng có cờ Cơ quan cấp chứng chỉ (nghĩa là được phép ký chứng chỉ). Sau đó, khi bạn mua chứng chỉ từ CA, họ ký CSR của bạn với một trong những chứng chỉ trung gian này.

Cửa hàng ủy thác Java của bạn rất có thể chỉ có Chứng chỉ gốc chứ không phải chứng chỉ trung gian.

Một trang web bị định cấu hình sai có thể chỉ trả lại chứng chỉ đã ký của họ. Vấn đề: nó đã được ký với một chứng chỉ trung gian không có trong cửa hàng ủy thác của bạn. Các trình duyệt sẽ xử lý vấn đề này bằng cách tải xuống hoặc sử dụng chứng chỉ trung gian được lưu trong bộ nhớ cache; điều này tối đa hóa khả năng tương thích trang web. Java và các công cụ như OpenSSL, tuy nhiên, sẽ không. Và điều đó sẽ gây ra lỗi trong câu hỏi.

Bạn có thể xác minh sự nghi ngờ này bằng cách sử dụng Kiểm tra SSL Qualys . Nếu bạn chạy nó trên một trang web và nó nói

Chuỗi chứng chỉ của máy chủ này không đầy đủ.

sau đó xác nhận nó. Bạn cũng có thể thấy điều này bằng cách nhìn vào các đường dẫn chứng nhận và xem văn bản Tải xuống thêm .

Cách khắc phục: quản trị viên máy chủ cũng cần định cấu hình máy chủ web để trả lại chứng chỉ trung gian. Ví dụ, đối với Comodo, đây là nơi .ca-bundletập tin có ích. Ví dụ: trong cấu hình Apache có mod_ssl, bạn sẽ sử dụng SSLCertificateChainFilecài đặt cấu hình. Đối với nginx, bạn cần ghép các chứng chỉ trung gian và chứng chỉ đã ký và sử dụng nó trong cấu hình chứng chỉ SSL. Bạn có thể tìm thêm bằng cách tìm kiếm "chuỗi chứng chỉ chưa hoàn thành" trực tuyến.


Bạn thông minh. Cảm ơn bạn! Tôi gặp sự cố với bản dựng mới của máy chủ Java của mình vì tôi quên xóa # trước SSLCert veChainFile !!! Thực sự giải thích tốt.
KisnardOnline

6

Lý do, chúng tôi nhận được lỗi ở trên là JDK được gói rất nhiều chứng chỉ Cơ quan cấp chứng chỉ (CA) đáng tin cậy vào một tệp có tên là 'cacerts' nhưng tệp này không có đầu mối của chứng chỉ tự ký của chúng tôi. Nói cách khác, tệp cacerts không được nhập chứng chỉ tự ký của chúng tôi và do đó không coi nó là một thực thể đáng tin cậy và do đó nó đưa ra lỗi trên.

Cách khắc phục lỗi trên

Để khắc phục lỗi trên, tất cả những gì chúng ta cần là nhập chứng chỉ tự ký vào tệp cacerts.

Đầu tiên, xác định vị trí tệp cacerts. Chúng ta sẽ cần tìm ra vị trí JDK. Nếu bạn đang chạy ứng dụng của mình thông qua một trong những IDE như Eclipse hoặc IntelliJ Idea, hãy đến các cài đặt dự án và tìm hiểu vị trí JDK là gì. Ví dụ: trên vị trí điển hình của tệp Macerts của tệp cacerts sẽ ở vị trí này / Thư viện / Java / JavaVirtualMachines / {{JDK_version}} / Nội dung / Trang chủ / jre / lib / bảo mật trên máy của Window, nó sẽ nằm trong {{Installer_directory} } / {{JDK_version}} / jre / lib / bảo mật

Khi bạn đã định vị tệp cacerts, bây giờ chúng ta cần nhập chứng chỉ tự ký vào tệp cacerts này. Kiểm tra bài viết cuối cùng, nếu bạn không biết cách tạo chứng chỉ tự ký chính xác.

Nếu bạn không có tệp chứng chỉ (.crt) và chỉ cần có tệp .jks, bạn có thể tạo tệp .crt bằng cách sử dụng lệnh bên dưới. Trong trường hợp bạn đã có tệp .crt / .pem thì bạn có thể bỏ qua lệnh bên dưới

## Để tạo chứng chỉ từ kho khóa (tệp .jks) ####

keytool -export -keystore keystore.jks -alias selfsigned -file selfsigned.crt

Bước trên sẽ tạo một tệp có tên là selfsign.crt. Bây giờ, nhập chứng chỉ vào cacerts

Bây giờ thêm chứng chỉ vào JRE / lib / security / cacerts (tin cậy)
keytool -importcert -file selfsigned.crt -alias selfsigned -keystore {{cacerts path}}

ví dụ

keytool -importcert -file selfsigned.nextgen.crt -alias selfsigned.nextgen -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/security/cacerts

Đó là tất cả, khởi động lại ứng dụng của bạn và nó sẽ hoạt động tốt. Nếu nó vẫn không hoạt động và có ngoại lệ bắt tay SSL. Nó có thể có nghĩa là bạn đang sử dụng tên miền khác nhau sau đó đăng ký trong chứng chỉ.

Liên kết với giải thích chi tiết và giải quyết từng bước là ở đây.


4

Thêm cacertskhông làm việc cho tôi. Sau khi kích hoạt nhật ký với cờ -Djavax.net.debug=all, sau đó biết java đọc từ jssecacerts.

Nhập khẩu để jssecacertslàm việc cuối cùng.


2
Giải thích còn thiếu ở đây là Java sẽ sử dụng jssecacertsnếu có, nếu không cacerts.
Hầu tước Lorne

3

Đây là một giải pháp nhưng dưới dạng câu chuyện của tôi với vấn đề này:

Tôi gần như đã chết khi thử tất cả các giải pháp được đưa ra ở trên (trong 3 ngày) và không có gì hiệu quả với tôi.

Tôi mất hết hy vọng.

Tôi đã liên lạc với nhóm bảo mật của mình về vấn đề này vì tôi đứng sau một proxy và họ nói rằng gần đây họ đã cập nhật chính sách bảo mật của họ.

Tôi đã mắng họ rất tệ vì đã không thông báo cho các Nhà phát triển.

Sau đó, họ đã phát hành một tệp "cacerts" mới chứa tất cả các chứng chỉ.

Tôi đã xóa tệp cacerts có trong% JAVA_HOME% / jre / lib / security và nó đã giải quyết được vấn đề của tôi.

Vì vậy, nếu bạn đang phải đối mặt với vấn đề này thì có thể là từ nhóm mạng của bạn cũng như thế này.


2

Tôi đã gặp câu hỏi này trong khi cố gắng cài đặt plugin Cucumber-Eclipse trong Eclipse thông qua trang web cập nhật của họ. Tôi đã nhận được cùng một lỗi SunCertPathBuilderException:

Unable to read repository at http://cucumber.io/cucumber-eclipse/update-site/content.xml.
    Unable to read repository at http://cucumber.io/cucumber-eclipse/update-site/content.xml.
    sun.security.validator.ValidatorException: PKIX path building failed: 
   sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Mặc dù một số câu trả lời khác là phù hợp và hữu ích cho tình huống được đưa ra của câu hỏi này, tuy nhiên chúng vẫn không có ích và gây hiểu lầm cho vấn đề của tôi.

Trong trường hợp của tôi, vấn đề là URL được cung cấp cho trang web cập nhật của họ là:

https://cucumber.io/cucumber-eclipse/update-site

Tuy nhiên, khi điều hướng đến nó thông qua trình duyệt, nó đã chuyển hướng đến (lưu ý thêm " .github "):

http://cucumber.github.io/cucumber-eclipse/update-site/

Vì vậy, độ phân giải chỉ đơn giản là sử dụng phiên bản được chuyển hướng của URL trang web cập nhật khi thêm trang web cập nhật trong nhật thực.


3
Bạn có chắc là bạn đang trả lời đúng câu hỏi? Không có đề cập đến dưa chuột trong câu hỏi ban đầu ...
Giải pháp dữ liệu đã hoàn thành

Tôi cảm thấy rằng tôi là. Tôi đã nhận được cùng một lỗi SunCertPathBuilderException và trong khi tìm kiếm một giải pháp, đã tìm thấy câu hỏi này cũng như câu hỏi này . Tuy nhiên, cả hai đều không có giải pháp thích hợp cho tình huống của tôi. Tôi đã không cố gắng trả lời câu hỏi cụ thể về cách thêm trang web bổ trợ Cucumber-Eclipse vào nhật thực. Tôi muốn cung cấp ngữ cảnh cho vấn đề tôi gặp phải (chuyển hướng URL) và giải thích cách giải quyết.
royfripple

Tôi đã cập nhật câu trả lời của mình để làm rõ rằng tôi đã nhận được cùng một lỗi, lưu ý rằng vấn đề và giải pháp cơ bản là khác nhau. Tôi cảm thấy điều này là hợp lệ vì những người khác có thể tìm thấy câu hỏi này khi tìm kiếm trên cùng một lỗi. Vui lòng xem xét thay đổi phiếu bầu của bạn nếu bạn cảm thấy điều này có ý nghĩa.
royfripple

Cảm ơn bạn. Làm cho mọi thứ rõ ràng hơn, đảo ngược downvote của tôi
Giải pháp dữ liệu đã hoàn thành

Không có gì! Và cảm ơn vì đã dành thời gian để xem xét lại.
royfripple

2

Tôi đã phải đối mặt với cùng một vấn đề và giải quyết nó bằng các bước đơn giản dưới đây:

1) Tải xuống InstallCert.java từ google

2) Biên dịch nó bằng javac InstallCert.java

3) Chạy InstallCert.java bằng cách sử dụng java InstallCert.java , với tên máy chủ và cổng https và nhấn vào 1 1 khi yêu cầu nhập liệu. Nó sẽ thêm các local localhost của Google như là một kho lưu trữ khóa đáng tin cậy và tạo một tệp có tên là jssecacerts canh như sau:

java InstallCert localhost: 443

4) sao chép jssecacerts vào thư mục $ JAVA_HOME / jre / lib / security

Nguồn chính để giải quyết vấn đề ở đây là:

https://ankurjain26.blogspot.in/2017/11/javaxnetsslsslhandshakeexception.html


1

Tôi đã giải quyết vấn đề này trên Windows Server 2016 bằng Java 8, bằng cách nhập chứng chỉ từ pkcs12cửa hàng vào cacertskho khóa.

Đường dẫn đến cửa hàng pkcs12:
C:\Apps\pkcs12.pfx

Đường dẫn tới các đoạn trích Java:
C:\Program Files\Java\jre1.8.0_151\lib\security\cacerts

Đường dẫn tới keytool:
C:\Program Files\Java\jre1.8.0_151\bin

Sau khi sở hữu thư mục với keytool trong dấu nhắc lệnh (với tư cách quản trị viên), lệnh nhập cert từ pkcs12đến cacertsnhư sau:
keytool -v -importkeystore -srckeystore C:\Apps\pkcs12.pfx -srcstoretype PKCS12 -destkeystore "C:\Program Files\Java\jre1.8.0_151\lib\security\cacerts" -deststoretype JKS

Bạn sẽ được nhắc:
1. nhập mật khẩu kho khóa đích (
mật khẩu mật khẩu , mặc định là "changeit") 2. nhập mật khẩu kho khóa nguồn (mật khẩu pkcs12)


Để các thay đổi có hiệu lực, hãy khởi động lại máy chủ (hoặc chỉ khởi động lại JVM).


1
Tôi đã sử dụng phương pháp này trên máy Mac và nó chỉ hoạt động. Chứng chỉ của tôi tất nhiên là tự ký và được tạo cho tôi đã nhập tệp .pfx mà tôi đã tạo trên máy chủ windows adfs của mình. Sử dụng Java 10 cho ứng dụng của tôi Cảm ơn
Shashikant Soni

0

Ở đây thông thường loại ngoại lệ này xảy ra khi có sự không phù hợp trong PATH của chứng chỉ tin cậy. Kiểm tra cấu hình hoặc đường dẫn yêu cầu chứng chỉ máy chủ này để liên lạc an toàn.


Bạn có thể vui lòng cho tôi biết cấu hình chính xác nơi tôi có thể cài đặt chứng chỉ. Thực tế tôi đang gặp vấn đề về vấn đề này, tôi đã cài đặt chứng chỉ liên quan đến vấn đề này bằng keytool , nó hoạt động trong khoảng 20-30 phút và sau đó máy chủ lại gặp lỗi tương tự. Làm ơn giúp tôi. Tôi đã bị mắc kẹt trong vấn đề này trong 2 ngày.
Deepak Gangore

Tôi nghĩ rằng chứng chỉ thay đổi cứ sau 20-30 phút
Vishwanath gowda k

Tôi gặp phải vấn đề tương tự nhưng vấn đề là: java của tôi chọn vị trí mặc định cho $ JAVA_HOME / lib / security / cacerts của các ứng dụng Java mặc dù tôi đã cung cấp -Djavax.net.ssl.trustStore = / myapp / app.jks về điều này: stackoverflow.com/questions/33821785/
Mạnh

0

Đối với tôi, lỗi chứng chỉ xuất hiện vì tôi có fiddler chạy ở chế độ nền và điều đó làm rối tung chứng chỉ. Nó hoạt động như một proxy rất gần và khởi động lại nhật thực.


cùng một thăm dò xảy ra trong nhật thực, ngay cả sau khi đóng tất cả các ứng dụng
arvindwill

0

bàn thắng:

  1. sử dụng kết nối https
  2. xác minh chuỗi SSL
  3. không đối phó với cacerts
  4. thêm chứng chỉ trong thời gian chạy
  5. không bị mất chứng chỉ từ cacerts

Làm thế nào để làm nó:

  1. xác định kho khóa riêng
  2. đưa chứng chỉ vào kho khóa
  3. xác định lại bối cảnh mặc định SSL với lớp tùy chỉnh của chúng tôi
  4. ???
  5. lợi nhuận

Tệp trình bao bọc kho khóa của tôi:

public class CertificateManager {

    private final static Logger logger = Logger.getLogger(CertificateManager.class);

    private String keyStoreLocation;
    private String keyStorePassword;
    private X509TrustManager myTrustManager;
    private static KeyStore myTrustStore;

    public CertificateManager(String keyStoreLocation, String keyStorePassword) throws Exception {
        this.keyStoreLocation = keyStoreLocation;
        this.keyStorePassword = keyStorePassword;
        myTrustStore = createKeyStore(keyStoreLocation, keyStorePassword);
    }

    public void addCustomCertificate(String certFileName, String certificateAlias)
            throws Exception {
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init((KeyStore) null);
        Certificate certificate = myTrustStore.getCertificate(certificateAlias);
        if (certificate == null) {
            logger.info("Certificate not exists");
            addCertificate(certFileName, certificateAlias);
        } else {
            logger.info("Certificate exists");
        }
        tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(myTrustStore);
        for (TrustManager tm : tmf.getTrustManagers()) {
            if (tm instanceof X509TrustManager) {
                setMytrustManager((X509TrustManager) tm);
                logger.info("Trust manager found");
                break;
            }
        }
    }

    private InputStream fullStream(String fname) throws IOException {
        ClassLoader classLoader = getClass().getClassLoader();
        InputStream resource = classLoader.getResourceAsStream(fname);
        try {
            if (resource != null) {
                DataInputStream dis = new DataInputStream(resource);
                byte[] bytes = new byte[dis.available()];
                dis.readFully(bytes);
                return new ByteArrayInputStream(bytes);
            } else {
                logger.info("resource not found");
            }
        } catch (Exception e) {
            logger.error("exception in certificate fetching as resource", e);
        }
        return null;
    }

    public static KeyStore createKeyStore(String keystore, String pass) throws Exception {
        try {
            InputStream in = CertificateManager.class.getClass().getResourceAsStream(keystore);
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(in, pass.toCharArray());
            logger.info("Keystore was created from resource file");
            return keyStore;
        } catch (Exception e) {
            logger.info("Fail to create keystore from resource file");
        }

        File file = new File(keystore);
        KeyStore keyStore = KeyStore.getInstance("JKS");
        if (file.exists()) {
            keyStore.load(new FileInputStream(file), pass.toCharArray());
            logger.info("Default keystore loaded");
        } else {
            keyStore.load(null, null);
            keyStore.store(new FileOutputStream(file), pass.toCharArray());
            logger.info("New keystore created");
        }
        return keyStore;
    }

    private void addCertificate(String certFileName, String certificateAlias) throws CertificateException,
            IOException, KeyStoreException, NoSuchAlgorithmException {
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        InputStream certStream = fullStream(certFileName);
        Certificate certs = cf.generateCertificate(certStream);
        myTrustStore.setCertificateEntry(certificateAlias, certs);
        FileOutputStream out = new FileOutputStream(getKeyStoreLocation());
        myTrustStore.store(out, getKeyStorePassword().toCharArray());
        out.close();
        logger.info("Certificate pushed");
    }

    public String getKeyStoreLocation() {
        return keyStoreLocation;
    }

    public String getKeyStorePassword() {
        return keyStorePassword;
    }
    public X509TrustManager getMytrustManager() {
        return myTrustManager;
    }
    public void setMytrustManager(X509TrustManager myTrustManager) {
        this.myTrustManager = myTrustManager;
    }
}

Lớp này sẽ tạo kho khóa nếu cần thiết và có thể quản lý các chứng chỉ bên trong nó. Bây giờ lớp cho bối cảnh SSL:

public class CustomTrustManager implements X509TrustManager {

    private final static Logger logger = Logger.getLogger(CertificateManager.class);

    private static SSLSocketFactory socketFactory;
    private static CustomTrustManager instance = new CustomTrustManager();
    private static List<CertificateManager> register = new ArrayList<>();

    public static CustomTrustManager getInstance() {
        return instance;
    }

    private X509TrustManager defaultTm;

    public void register(CertificateManager certificateManager) {
        for(CertificateManager manager : register) {
            if(manager == certificateManager) {
                logger.info("Certificate manager already registered");
                return;
            }
        }
        register.add(certificateManager);
        logger.info("New Certificate manager registered");
    }

    private CustomTrustManager() {
        try {
            String algorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);

            tmf.init((KeyStore) null);
            boolean found = false;
            for (TrustManager tm : tmf.getTrustManagers()) {
                if (tm instanceof X509TrustManager) {
                    defaultTm = (X509TrustManager) tm;
                    found = true;
                    break;
                }
            }
            if(found) {
                logger.info("Default trust manager found");
            } else {
                logger.warn("Default trust manager was not found");
            }

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[]{this}, null);
            SSLContext.setDefault(sslContext);
            socketFactory = sslContext.getSocketFactory();
            HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory);


            logger.info("Custom trust manager was set");
        } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
            logger.warn("Custom trust manager can't be set");
            e.printStackTrace();
        }
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        List<X509Certificate> out = new ArrayList<>();
        if (defaultTm != null) {
            out.addAll(Arrays.asList(defaultTm.getAcceptedIssuers()));
        }
        int defaultCount = out.size();
        logger.info("Default trust manager contain " + defaultCount + " certficates");
        for(CertificateManager manager : register) {
            X509TrustManager customTrustManager = manager.getMytrustManager();
            X509Certificate[] issuers = customTrustManager.getAcceptedIssuers();
            out.addAll(Arrays.asList(issuers));
        }
        logger.info("Custom trust managers contain " + (out.size() - defaultCount) + " certficates");
        X509Certificate[] arrayOut = new X509Certificate[out.size()];
        return out.toArray(arrayOut);
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain,
                                   String authType) throws CertificateException {
        for(CertificateManager certificateManager : register) {
            X509TrustManager customTrustManager = certificateManager.getMytrustManager();
            try {
                customTrustManager.checkServerTrusted(chain, authType);
                logger.info("Certificate chain (server) was aproved by custom trust manager");
                return;
            } catch (Exception e) {
            }
        }
        if (defaultTm != null) {
            defaultTm.checkServerTrusted(chain, authType);
            logger.info("Certificate chain (server) was aproved by default trust manager");
        } else {
            logger.info("Certificate chain (server) was rejected");
            throw new CertificateException("Can't check server trusted certificate.");
        }
    }

    @Override
    public void checkClientTrusted(X509Certificate[] chain,
                                   String authType) throws CertificateException {
        try {
            if (defaultTm != null) {
                defaultTm.checkClientTrusted(chain, authType);
                logger.info("Certificate chain (client) was aproved by default trust manager");
            } else {
                throw new NullPointerException();
            }
        } catch (Exception e) {
            for(CertificateManager certificateManager : register) {
                X509TrustManager customTrustManager = certificateManager.getMytrustManager();
                try {
                    customTrustManager.checkClientTrusted(chain, authType);
                    logger.info("Certificate chain (client) was aproved by custom trust manager");
                    return;
                } catch (Exception e1) {
                }
            }
            logger.info("Certificate chain (client) was rejected");
            throw new CertificateException("Can't check client trusted certificate.");
        }
    }

    public SSLSocketFactory getSocketFactory() {
        return socketFactory;
    }
}

Lớp này được tạo dưới dạng singleton, vì chỉ cho phép một bối cảnh mặc địnhSSL. Vì vậy, bây giờ sử dụng:

            CertificateManager certificateManager = new CertificateManager("C:\\myapplication\\mykeystore.jks", "changeit");
            String certificatePath = "C:\\myapplication\\public_key_for_your_ssl_service.crt";
            try {
                certificateManager.addCustomCertificate(certificatePath, "alias_for_public_key_for_your_ssl_service");
            } catch (Exception e) {
                log.error("Can't add custom certificate");
                e.printStackTrace();
            }
            CustomTrustManager.getInstance().register(certificateManager);

Có thể, nó sẽ không hoạt động với cài đặt này, vì tôi giữ tệp chứng chỉ bên trong thư mục tài nguyên, vì vậy đường dẫn của tôi không tuyệt đối. Nhưng nói chung, nó hoạt động hoàn hảo.


1
Việc lạm dụng kép available()này được cảnh báo cụ thể chống lại Javadoc của chính nó.
Hầu tước Lorne

0

Đó là bổ sung cho câu trả lời https://stackoverflow.com/a/36427118/1491414 . Cảm ơn @MagGGG

  • Vui lòng đảm bảo rằng bạn có sự cho phép của quản trị viên
  • Vui lòng sử dụng dấu ngoặc kép cho đường dẫn kho khóa (-keystore C: \ Program Files (x86) \ Java \ jre1.6.0_22 \ lib \ security \ cacerts ") vì trong Windows OS, vị trí cài đặt mặc định sẽ là Tệp chương trình và bạn sẽ nhận được một lỗi vì không gian giữa các tệp chương trình.

0

Tôi đã sửa lỗi này bằng phương pháp dưới đây-

  1. Sao chép url đang gặp sự cố kết nối
  2. Chuyển đến Android Studio-> Cài đặt-> Cài đặt http
  3. Trong 'Kiểm tra kết nối', dán url đó và nhấn ok
  4. Khi nhấp vào Ok, Android Studio sẽ yêu cầu nhập chứng chỉ của url đó, nhập nó
  5. Đó là nó. Không có gì khác để làm và vấn đề của tôi đã biến mất. Không cần phải khởi động lại studio là tốt.

0

Khi bạn có lỗi ở trên với phần mềm atlassian ex. jira

2018-08-18 11:35:00,312 Caesium-1-4 WARN anonymous    Default Mail Handler [c.a.mail.incoming.mailfetcherservice] Default Mail Handler[10001]: javax.mail.MessagingException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target while connecting to host 'imap.xyz.pl' as user 'jira@xyz.pl' via protocol 'imaps, 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

bạn có thể thêm certs vào kho khóa đáng tin cậy của nó (thay đổi mất_ca thành tên chứng chỉ phù hợp):

keytool -importcert -file missing_ca.crt -alias missing_ca -keystore /opt/atlassian/jira/jre/lib/security/cacerts

Nếu được hỏi nhập mật khẩu changeitvà xác nhậny

Sau đó chỉ cần khởi động lại jira.


0

Nếu URL kho lưu trữ của bạn cũng hoạt động trên HTTP và bảo mật không phải là vấn đề đáng lo ngại, bạn có thể truy cập settings.xml (thường xuyên, nhưng không phải luôn luôn, nằm trong %USERPROFILE%/.m2) và thay thế HTTPS bằng HTTP cho <repository><pluginRepository>URL.

Ví dụ: cái này:

<repository>
    <snapshots>
        <enabled>false</enabled>
    </snapshots>
    <id>central</id>
    <name>libs-release</name>
    <url>https://<artifactory>/libs-release</url>
</repository>

nên được thay thế bởi điều này:

<repository>
    <snapshots>
        <enabled>false</enabled>
    </snapshots>
    <id>central</id>
    <name>libs-release</name>
    <url>https://<artifactory>/libs-release</url>
</repository>

0

Tôi đã sử dụng cửa hàng ủy thác của riêng mình chứ không phải JRE bằng cách thông qua arg -Djavax.net.ssl.trustStore=

Tôi đã nhận được lỗi này bất kể certs trong Truststore. Vấn đề đối với tôi là thứ tự của các thuộc tính được truyền trên dòng arg. Khi tôi đặt -Djavax.net.ssl.trustStore=& -Djavax.net.ssl.trustStorePassword= trước -Dspring.config.location= & -jarargs tôi đã có thể gọi thành công cuộc gọi còn lại của mình qua https.


0

Nếu bạn đang sử dụng CloudFoundry và gặp phải vấn đề về chứng chỉ thì bạn phải đảm bảo rằng bạn lại đẩy bình với dịch vụ kho khóa có chứng chỉ trong đó. Đơn giản chỉ cần hủy liên kết, liên kết và khởi động lại sẽ không hoạt động.


0

Trong trường hợp máy chủ của bạn ngồi sau tường lửa / proxy , hãy sử dụng lệnh sau trong cmd:

keytool -J-Dhttps.proxyHost=<proxy_hostname> -J-Dhttps.proxyPort=<proxy_port> -printcert -rfc -sslserver <remote_host_name:remote_ssl_port>

Thay thế <proxy_hostname><proxy_port>với máy chủ proxy HTTP được định cấu hình. Thay thế<remote_host_name:remote_ssl_port> bằng một trong các máy chủ từ xa (về cơ bản là url) và cổng có vấn đề về chứng nhận.

Lấy nội dung chứng chỉ cuối cùng được in và sao chép nó (cũng sao chép chứng chỉ bắt đầu và kết thúc). Dán nó vào tệp văn bản và cung cấp phần mở rộng .crt cho nó. Bây giờ, nhập chứng chỉ này vào cacerts bằng lệnh java keytool và nó sẽ hoạt động.

keytool -importcert -file <filename>.crt -alias randomaliasname -keystore %JAVA_HOME%/jre/lib/security/cacerts -storepass changeit

0

Hãy thử sao chép các đoạn trích java:

cp /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.172-9.b11.fc28.x86_64/jre/lib/security/cacerts $JAVA_HOME/jre/lib/security/cacerts


0

Nếu bạn gặp vấn đề này trong một thùng chứa linux khi ứng dụng java đang cố gắng giao tiếp với một ứng dụng / trang web khác, thì đó là do chứng chỉ đã được nhập không chính xác vào bộ cân bằng tải. Có một loạt các bước cần tuân thủ để nhập chứng chỉ và nếu không được thực hiện đúng, bạn sẽ thấy các vấn đề như

Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid 
certification path to requested target

Một khi các certs được nhập chính xác, nó nên được thực hiện. Không cần phải tinker với bất kỳ certs JDK.


0

Tôi đã giải quyết nó cho Intellij Idea Tôi gặp phải vấn đề này Althouh, tôi thay đổi rất nhiều nơi để giải quyết vấn đề. Tôi tìm thấy giải pháp cho tôi. Hãy nhấp vào dự án của bạn, bạn sẽ thấy Maven , sau đó nhấn Tạo nguồn và cập nhật thư mục ReImport nhập mô tả hình ảnh ở đây

Thế là xong.


0

Tôi đã phải đối mặt với cùng một vấn đề, tôi đã sử dụng 8.1.0-3, nhưng sau đó tôi đã sử dụng 9.2.1-0 và vấn đề đã được khắc phục mà không cần bất kỳ bước thủ công nào. Giấy chứng nhận tự ký làm việc tốt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.