„Budowanie ścieżki PKIX nie powiodło się” i „nie można znaleźć prawidłowej ścieżki certyfikacji do żądanego celu”

422

Próbuję uzyskać tweety za pomocą biblioteki twitter4j dla mojego projektu Java. Przy pierwszym uruchomieniu dostałem błąd dotyczący certyfikatu sun.security.validator.ValidatorExceptioni sun.security.provider.certpath.SunCertPathBuilderException. Następnie dodałem certyfikat Twittera przez:

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"

Ale bez powodzenia. Oto procedura pobierania tweetów:

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

A oto błąd:

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
Dozent
źródło
6
Witaj Proszę sprawdzić poniżej URL. Jestem pewien, że ci to pomogą. java-samples.com/showtutorial.php?tutorialid=210 confluence.atlassian.com/display/JIRAKB/… . Musisz dodać swój certyfikat ssl do certyfikatu zaufanego magazynu Java (Ścieżka: jre / lib / security / cacerts).
sus007,
Proszę odnieść to odpowiedź dla rozwiązania oraz potwierdzają jesteś pakowania oprogramowania jak dołączonemu JRE? jeśli tak, skopiuj system plików cacerts i zamień spakowany plik jre cacerts.
positivecrux
spróbuj tego stackoverflow.com/a/9210661/4741746 być może to jest twoja odpowiedź
sushant gosavi
2
Właśnie użyłem tego kodu Java i dla https nie zapomnij podać portu jako 443. Kod Java na github.com/escline/InstallCert/blob/master/InstallCert.java To zajmie twój plik CACERTS i doda wszystkie plus aktualny certyfikat dla adresu URL podanego jako dane wejściowe. W moim przypadku zakodowałem wartości na host = "mywebservice.uat.xyz.com"; port = 443; passphrase = "changeit" .toCharArray (); Następnie program tworzy nowy plik o nazwie „jssecacerts”, który będzie zawierał wszystko. Zmień nazwę na „cacerts” i użyj tego. Wszystko będzie gotowe.
Reddymails

Odpowiedzi:

572
  1. Przejdź do adresu URL w przeglądarce:
    • firefox - kliknij łańcuch certyfikatów HTTPS (ikona kłódki obok adresu URL). Kliknij "more info" > "security" > "show certificate" > "details" > "export..". Odbierz nazwę i wybierz typ pliku example.cer
    • chrome - kliknij ikonę strony w lewo, aby zaadresować w pasku adresu, wybierz „Certyfikat” -> „Szczegóły” -> „Eksportuj” i zapisz w formacie „Kod binarny z kodowaniem Der, pojedynczy certyfikat”.
  2. Teraz masz plik z magazynem kluczy i musisz go dodać do JVM. Określ lokalizację plików cacerts, np. C:\Program Files (x86)\Java\jre1.6.0_22\lib\security\cacerts.

  3. Następnie zaimportuj example.cerplik do cacerts w wierszu poleceń:

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

Zostaniesz poproszony o podanie hasła, które jest domyślne changeit

Uruchom ponownie JVM / PC.

źródło: http://magicmonster.com/kb/prg/java/ssl/pkix_path_building_failed.html

MagGGG
źródło
27
Musiałem umieścić ścieżkę w cudzysłowie, a także zapisać ją jako Base64 zamiast DER
Theodore K.
3
wow ... to przy okazji działało jak magia, wystarczy kliknąć ikonę kłódki na lewym pasku adresu, a następnie kliknąć szczegóły i nie trzeba restartować
aswzen
8
Pamiętaj, że instrukcje należy powtórzyć dla wszystkich certyfikatów w łańcuchu. Również aliasnazwa certyfikatu w wierszu poleceń powinna być unikalna.
Lu55
5
Jeśli twoim domem jest JDK, pamiętaj, aby określić, że jre jest w tym: keytool -import -alias example -keystore "C: \ Program Files \ Java \ jdk1.8.0_73 \ jre \ lib \ security \ cacerts" -plik przyklad.cer
Jack BeNimble
12
Dla każdego, kto otrzyma błąd „odmowa dostępu”, upewnij się, że uruchamiasz wiersz polecenia jako administrator.
Walker Christie
81

Po wielu godzinach prób zbudowania plików certyfikatów, aby moja instalacja Java 6 działała z nowymi certyfikatami Twitter, w końcu natknąłem się na niezwykle proste rozwiązanie ukryte w komentarzu na jednym z forów dyskusyjnych. Po prostu skopiuj plik cacerts z instalacji Java 7 i zastąp ten plik w instalacji Java 6. Prawdopodobnie najlepiej najpierw zrobić kopię zapasową pliku cacerts, ale potem wystarczy skopiować nowy plik i BOOM! to po prostu działa.

Zauważ, że faktycznie skopiowałem plik Windows Cacerts do instalacji Linuksa i działał dobrze.

Plik znajduje się jre/lib/security/cacertszarówno w starej, jak i nowej instalacji Java JDK.

Mam nadzieję, że to ocali komuś godziny pogorszenia.

Jeremy Goodell
źródło
4
Próbuję uzyskać dostęp do serwera ssl z certyfikatem z podpisem własnym, próbowałem dodać jego certyfikat za pomocą keytoola, ale bez powodzenia, jakieś sugestie?
Oleg Belousov
1
Cieszę się, że zadziałało .. Ale czy wiesz, co było przyczyną. co sprawiło, że zawiodło z java 6 cert .. i jak java 7 cert rozwiązało problem
Vishwanath gowda k
Zrobiło to, chociaż przeszedłem z icedtea 1.6 na oracle 1.7. :)
nperson325681
Weź
10
Dla tych, którzy lubią mnie, czasem brakuje tego, co oczywiste - upewnij się, że w to wchodzisz $JAVA_HOME/jre/lib, a nie $JAVA_HOME/lib- spędziłem trochę czasu, omijając ten szczegół.
Ryan Heathcote
35

Podejście MY UI:

  1. Pobierz tutaj eksplorator kluczy
  2. Otwórz $ JAVA_HOME / jre / lib / security / cacerts
  3. wpisz PW: changeit (Może być zmieniony na Macu)
  4. Zaimportuj plik .crt

CMD-Line:

  1. keytool -importcert -file jetty.crt -alias jetty -keystore $JAVA_HOME/jre/lib/security/cacerts
  2. wpisz PW: changeit(Może być zmieniony na Macu)
Mike Mitterer
źródło
1
Na Macu, z CMD-Line, należy użyć sudo, aby uruchomić polecenie. # sudo keytool -importcert -plik jetty.crt -alias jetty -keystore $ JAVA_HOME / jre / lib / security / cacerts
malajisi
1
W systemie Windows polecenie, które działa:keytool -importcert -file dinardap_cert.cer –alias dinardap –keystore “%JAVA_HOME%/jre/lib/security/cacerts”
Patricio Bonilla
skąd wziąć plik cert? Nie wiem, do którego adresu URL należy przejść. jetty.com ?
kraftydevil
Dostaję mój certyfikat, eksportując go z przeglądarki internetowej, akcja kontekstowa na
kłódce
28

Natknąłem się na ten problem, który wymagał wielu godzin badań, zwłaszcza w przypadku automatycznie generowanych certyfikatów, które w przeciwieństwie do oficjalnych, są dość trudne i Java ich nie lubi.

Sprawdź następujący link: Rozwiąż problem z certyfikatami w Javie

Zasadniczo musisz dodać certyfikat z serwera do certyfikatów Java Home.

  1. Wygeneruj lub pobierz certyfikat i skonfiguruj Tomcat, aby używał go w Servers.xml
  2. Pobierz kod źródłowy Java klasy InstallCerti uruchom go podczas działania serwera, podając następujące argumentyserver[:port] . Hasło nie jest potrzebne, ponieważ oryginalne hasło działa dla certyfikatów Java („changeit”).
  3. Program połączy się z serwerem, a Java wyrzuci wyjątek, przeanalizuje certyfikat dostarczony przez serwer i pozwoli ci utworzyć jssecertsplik w katalogu, w którym wykonałeś program (jeśli wykonano go z Eclipse, upewnij się, że skonfigurowałeś Work katalog wRun -> Configurations ).
  4. Ręcznie skopiuj ten plik do $JAVA_HOME/jre/lib/security

Po wykonaniu tych kroków połączenia z certyfikatem nie będą już generować wyjątków w Javie.

Poniższy kod źródłowy jest ważny i zniknął z blogów Oracle (Sun), jedyna strona, którą znalazłem, był pod podanym linkiem, dlatego dołączam go w odpowiedzi na wszelkie odniesienia.

/*
 * 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);
        }
    }
}
will824
źródło
2
Uwaga: utworzony plik to jssecacerts!
DeanDP
Próbowałem użyć tego rozwiązania dla Java 7 i 8. Podczas pracy na Javie 7 otrzymałem wersję_programu lub błąd_sprzężenia dla wszystkich adresów URL zdalnego repozytorium, z którymi próbowałem. 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. Sprawdź certyfikat

Spróbuj załadować docelowy adres URL w przeglądarce i przejrzeć certyfikat witryny (zwykle jest dostępny za pomocą ikony ze znakiem blokady. Znajduje się po lewej lub prawej stronie paska adresu przeglądarki), niezależnie od tego, czy wygasł, czy nie był z innych powodów niezaufany.

2. Zainstaluj najnowsze wersje JRE i JDK

Nowe wersje zwykle zawierają zaktualizowany zestaw zaufanych certyfikatów.

Również jeśli to możliwe, odinstaluj stare wersje. Sprawi to, że błędy w konfiguracji będą jawne.

3. Sprawdź konfigurację:

  • Sprawdź, gdzie wskazuje twoja zmienna środowiskowa JAVA_HOME.
  • Sprawdź, której wersji Java używasz do uruchamiania programu. W IntelliJ sprawdź:
    • Plik -> Struktura projektu ... -> Ustawienia projektu -> Projekt -> Zestaw SDK projektu:
    • Plik -> Struktura projektu ... -> Ustawienia platformy -> SDK

4. Skopiuj cały magazyn kluczy z nowej wersji Java

Jeśli tworzysz w JDK innym niż najnowszy dostępny - spróbuj zastąpić %JAVA_HOME%/jre/lib/security/cacertsplik nowym plikiem z najnowszego zainstalowanego środowiska JRE (najpierw wykonaj kopię zapasową), jak sugeruje @ jeremy-goodell w swojej odpowiedzi

5. Dodaj certyfikaty do swojego magazynu kluczy

Jeśli nic powyżej nie rozwiązuje problemu, użyj keytoolcertyfikatu (ów) do magazynu kluczy Java:

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

Plik z certyfikatem można uzyskać z przeglądarki, jak sugeruje @MagGGG w swojej odpowiedzi .

Uwaga 1: może być konieczne powtórzenie tego dla każdego certyfikatu w łańcuchu do certyfikatu witryny. Zacznij od roota.

Uwaga 2: <alias_name>powinna być unikalna wśród kluczy w sklepie lubkeytool pokaże błąd.

Aby uzyskać listę wszystkich certyfikatów w sklepie, możesz uruchomić:

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

Jeśli coś pójdzie nie tak, pomoże Ci to usunąć certyfikat ze sklepu:

keytool -delete -alias <alias_name> -keystore "%JAVA_HOME%jre\lib\security\cacerts" -storepass changeit
Lu55
źródło
Biorąc pod uwagę, jak dobrze jest to opracowane, powinna to być zaakceptowana odpowiedź.
Egor Hans
13
-Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true

Służy do przeskoczenia sprawdzania poprawności certyfikatu.

Ostrzeżenie Używanie tylko do celów programistycznych w tym celu jest niepewne!

gorums
źródło
4
Służy do skoku sprawdzania poprawności certyfikatu
gorums
2
@gorums Jak to skonfigurować w Eclipse?
malajisi
6
NIE rób tego, chyba że chcesz zaryzykować uruchomienie dowolnego złośliwego kodu na swoim komputerze. Odebrane, ponieważ grozi to naruszeniem bezpieczeństwa komputera, na którym jest uruchomiony.
Bryan
1
Tylko dlatego, że „działa”, nie oznacza, że ​​jest bezpieczny, narażasz każdego, kto postępuje zgodnie z tą radą. Oddajcie głos
Paradoxis,
1
@AceKing Chodzi o to, że nie jest to zaufany kod, jeśli nie sprawdzasz poprawności certyfikatu. To powiedziawszy, myślę, że to wciąż przydatna odpowiedź. Ludzie, którzy to robią, muszą zrozumieć ryzyko.
Michael Mior
12

Miałem nieco inną sytuację, gdy zarówno JDK, jak i JRE 1.8.0_112 były obecne w moim systemie.

Zaimportowałem nowe certyfikaty CA, [JDK_FOLDER]\jre\lib\security\cacertsużywając już znanego polecenia:

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

Nadal otrzymywałem ten sam błąd podczas budowania ścieżki PKIX .

Dodałem informacje debugowania do interfejsu CLI Java, używając java -Djavax.net.debug=all ... > debug.log. W pliku debug.log wiersz rozpoczynający się od trustStore to: faktycznie wskazywał na sklep cacerts znaleziony w[JRE_FOLDER]\lib\security\cacerts .

W moim przypadku rozwiązaniem było skopiowanie pliku cacerts używanego przez JDK (z dodanymi nowymi urzędami certyfikacji) na plik używany przez JRE i to rozwiązało problem.

MF
źródło
Za pomocą keytool zaimportowałem bezpośrednio potrzebne certyfikaty do JRE / lib / security / cacerts, ale nic mi to nie zmieniło :( wciąż otrzymuję ten sam błąd, dodałem je również przez IDE, a nawet ścieżkę klas i dodałem Bean do podaj lokalizację magazynu kluczy !! To szalony AF!
Alex
8

Tło problemu:

Pojawił się następujący błąd podczas próby uruchomienia instalacji mvn clean w moim projekcie i poprzez opcję Netbeans IDE czyszczenia i kompilacji. Ten problem wynika z faktu, że certyfikat nie jest dostępny, gdy pobieramy przez NET bean IDE / przez wiersz polecenia, ale możemy pobrać pliki przez przeglądarkę.

Błąd :

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  

Rozkład:

1. Pobierz certyfikat odnośnego adresu URL:

  • Uruchom IE przez „uruchom jako administrator” (w przeciwnym razie nie będziemy mogli pobrać certyfikatu)
  • Wpisz adres URL w IE-> https: // url / local-repo (W moim przypadku ten adres URL miał niezaufany certyfikat wprowadź opis zdjęcia tutaj).
  • Pobierz certyfikat, klikając Błąd certyfikatu -> wyświetl certyfikat
  • Wybierz kartę Szczegóły -> skopiuj do pliku -> dalej -> wybierz „Kod binarny X.509 (.CER) zakodowany w DER
  • zapisz certyfikat w pewnej lokalizacji, na przykład: c: /user/sheldon/desktop/product.cer
  • Gratulacje! pomyślnie pobrałeś certyfikat dla witryny

2. Teraz zainstaluj magazyn kluczy, aby rozwiązać problem.

  • Uruchom komendę keytool, aby dodać pobrany plik kluczy do istniejącego pliku certyfikatu.
  • Polecenie: poniżej polecenia w folderze bin jdk (JAVA_HOME) .

C: \ Program Files \ Java \ jdk1.8.0_141 \ jre \ bin> keytool -importcert -file "C: /user/sheldon/desktop/product.cer" -alias product -keystore "C: / Program Files / Java / jdk1.8.0_141 / jre / lib / security / cacerts ".

  • Zostaniesz poproszony o podanie hasła. Wprowadź hasło do magazynu kluczy: wpisz ponownie „zmień” w polu „Ufaj temu certyfikatowi? [Nie]:”, wpisz „tak”

Przykładowe polecenia / dane wyjściowe z wiersza poleceń:

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
  • Gratulacje! teraz powinieneś pozbyć się błędu „Budowanie ścieżki PKIX nie powiodło się: sun.security.provider.certpath.SunCertPathBuilderException” w twoim IDE Netbeans.
Barani r
źródło
Cześć Śledziłem wszystkie kroki, ale bez powodzenia :(
ManishNegi
czy masz jakiś inny certyfikat na ścieżce niż cacerts? jeśli masz jakieś inne, spróbuj dodać je do tego certyfikatu
Barani r
Dzięki @Barani r, to był mój błąd, że wykonywałem polecenie z Jre i
używałem
Nie udało się pobrać certyfikatu, ale potem „uruchom jako administrator” działało dobrze.
Kolejny koder
8

Chciałem zaimportować certyfikat dla smtp.gmail.com

Jedynym rozwiązaniem, które działało dla mnie, jest 1. Wpisz polecenie, aby wyświetlić ten certyfikat

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

  1. Skopiuj i zapisz linie między „----- ROZPOCZNIJ CERTYFIKAT -----” i „----- ZAKOŃCZ CERTYFIKAT -----” w pliku gmail.cer

  2. Biegać

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

  3. Wpisz hasło chageit

  4. Kliknij przycisk tak, aby zaimportować certyfikat

  5. Uruchom ponownie java

teraz uruchom polecenie i możesz już iść

Sneha Shejwal
źródło
Dziękuje! To uratowało mi dzień. To było jedyne właściwe rozwiązanie w moim przypadku.
Andrew Gans,
Uratowałem też mój dzień. Dziękuję Ci.
Kris,
6

To nie jest odpowiedź na Twittera, ale to pytanie pojawia się, gdy szukasz tego błędu. Jeśli system otrzymuje ten błąd podczas łączenia się z witryną, która wydaje się mieć prawidłowy certyfikat podczas przeglądania w przeglądarce internetowej , prawdopodobnie oznacza to, że witryna ma niekompletny łańcuch certyfikatów .

Krótkie podsumowanie problemu: urzędy certyfikacji nie używają swojego certyfikatu głównego do podpisywania tylko starych certyfikatów. Zamiast tego (zwykle) podpisują pośrednie certyfikaty które również mają ustawioną flagę ośrodka certyfikacji (tzn. Mogą podpisywać certyfikaty). Następnie, kupując certyfikat od urzędu certyfikacji, podpisują on raport CSR jednym z tych certyfikatów pośrednich.

Twój sklep zaufania Java najprawdopodobniej ma tylko certyfikat główny, a nie pośredni.

Błędnie skonfigurowana witryna może po prostu wrócić podpisany certyfikat. Problem: został podpisany pośrednim certyfikatem, którego nie ma w twoim magazynie zaufania. Przeglądarki poradzą sobie z tym problemem poprzez pobranie lub użycie buforowanego certyfikatu pośredniego; maksymalizuje to kompatybilność strony internetowej. Jednak Java i narzędzia takie jak OpenSSL nie będą. A to spowoduje błąd w pytaniu.

Możesz zweryfikować to podejrzenie za pomocą testu Qualys SSL . Jeśli uruchomisz to na stronie i to powie

Łańcuch certyfikatów tego serwera jest niekompletny.

to to potwierdza. Możesz to również zobaczyć, patrząc na ścieżki certyfikacji i tekst Extra Download .

Jak to naprawić: administrator serwera musi tak skonfigurować serwer WWW, aby zwracał również certyfikaty pośrednie. Na przykład w Comodo przydatny jest .ca-bundleplik. Na przykład w konfiguracji Apache z mod_ssl użyłbyś SSLCertificateChainFileustawienia konfiguracji. W przypadku Nginx musisz połączyć certyfikaty pośrednie i podpisany certyfikat i użyć go w konfiguracji certyfikatu SSL. Aby znaleźć więcej, wyszukaj „niekompletny łańcuch certyfikatów” online.

Reid
źródło
Jesteś wspaniały. Dziękuję Ci! Miałem problem z nową wersją mojego serwera Java, ponieważ zapomniałem usunąć # przed SSLCertificateChainFile !!! Naprawdę dobrze wyjaśnione.
KisnardOnline
6

Przyczyną powyższego błędu jest to, że JDK jest pakowany z wieloma zaufanymi certyfikatami urzędu certyfikacji (CA) w plik o nazwie „cacerts”, ale ten plik nie ma pojęcia o naszym certyfikacie z podpisem własnym. Innymi słowy, plik cacerts nie ma zaimportowanego naszego certyfikatu z podpisem własnym, a zatem nie traktuje go jako zaufanego podmiotu i dlatego powoduje powyższy błąd.

Jak naprawić powyższy błąd

Aby naprawić powyższy błąd, wystarczy zaimportować samopodpisany certyfikat do pliku cacerts.

Najpierw zlokalizuj plik cacerts. Musimy znaleźć lokalizację JDK. Jeśli uruchamiasz aplikację za pośrednictwem jednego z IDE, takich jak Eclipse lub IntelliJ Idea, przejdź do ustawień projektu i dowiedz się, jaka jest lokalizacja JDK. Na przykład w systemie Mac OS typowa lokalizacja pliku cacerts byłaby w tej lokalizacji / Library / Java / JavaVirtualMachines / {{JDK_version}} / Contents / Home / jre / lib / security na komputerze z systemem Windows, to w {{katalog_instalacyjny} } / {{JDK_version}} / jre / lib / security

Po zlokalizowaniu pliku cacerts musimy teraz zaimportować nasz samopodpisany certyfikat do tego pliku cacerts. Sprawdź ostatni artykuł, jeśli nie wiesz, jak poprawnie wygenerować samopodpisany certyfikat.

Jeśli nie masz pliku certyfikatu (.crt) i po prostu masz plik .jks, możesz wygenerować plik .crt za pomocą poniższej komendy. Jeśli masz już plik .crt / .pem, możesz zignorować poniższe polecenie

## Aby wygenerować certyfikat z magazynu kluczy (plik .jks) ####

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

Powyższy krok wygeneruje plik o nazwie selfsigned.crt.Now Zaimportuj certyfikat do cacerts

Teraz dodaj certyfikat do JRE / lib / security / cacerts (trustore)
keytool -importcert -file selfsigned.crt -alias selfsigned -keystore {{cacerts path}}

na przykład

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

To wszystko, uruchom ponownie aplikację i powinna działać poprawnie. Jeśli nadal nie działa i uzyskaj wyjątek uzgadniania SSL. Prawdopodobnie oznacza to, że używasz innej domeny niż zarejestrowana w certyfikacie.

Link ze szczegółowym wyjaśnieniem i krok po kroku znajduje się tutaj.

Abhishek Galoda
źródło
4

Dodawanie cacertsnie działało dla mnie. Po włączeniu dziennika z flagą -Djavax.net.debug=allpoznałem czytanie z języka Java jssecacerts.

W jssecacertskońcu zaimportuj .

alk453
źródło
2
Brakującym wyjaśnieniem jest to, że Java użyje, jssecacertsjeśli jest obecna, w przeciwnym razie cacerts.
Markiz Lorne
3

To rozwiązanie, ale w formie mojej historii z tym problemem:

Byłem prawie martwy, wypróbowując wszystkie powyższe rozwiązania (przez 3 dni) i nic nie działało dla mnie.

Straciłem wszelką nadzieję.

Skontaktowałem się z moim zespołem ds. Bezpieczeństwa w tej sprawie, ponieważ byłem za serwerem proxy i powiedzieli, że niedawno zaktualizowali swoją politykę bezpieczeństwa.

Źle ich skarciłem za to, że nie informowali programistów.

Później wydali nowy plik „cacerts”, który zawiera wszystkie certyfikaty.

Usunąłem plik cacerts, który jest obecny w% JAVA_HOME% / jre / lib / security i to rozwiązało mój problem.

Więc jeśli masz do czynienia z tym problemem, może to być również twój zespół sieciowy.

Vikash Kumar
źródło
2

Natknąłem się na to pytanie, próbując zainstalować wtyczkę Cucumber-Eclipse w Eclipse za pośrednictwem witryny aktualizacji. Otrzymałem ten sam błąd 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

Chociaż niektóre z pozostałych odpowiedzi są odpowiednie i pomocne w danej sytuacji tego pytania, były jednak nieprzydatne i mylące dla mojego problemu.

W moim przypadku problemem było to, że adres URL podany dla ich witryny aktualizacji to:

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

Jednak podczas nawigowania do niego za pomocą przeglądarki przekierowano do (zwróć uwagę na dodane „ .github ”):

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

Dlatego rozwiązaniem jest po prostu użycie przekierowanej wersji adresu URL witryny aktualizacji podczas dodawania witryny aktualizacji w środowisku eclipse.

Royfripple
źródło
3
Czy na pewno odpowiadasz na właściwe pytanie? W pierwotnym pytaniu nie ma wzmianki o ogórku ...
Done Data Solutions
Czuję, że jestem. Otrzymałem ten sam błąd SunCertPathBuilderException i szukając rozdzielczości, znalazłem to pytanie, jak również to . Jednak żadne z nich nie miało odpowiedniego rozwiązania dla mojej sytuacji. Nie próbowałem odpowiedzieć na konkretne pytanie, jak dodać witrynę wtyczek Cucumber-Eclipse do zaćmienia. Chciałem podać kontekst dla napotkanego problemu (przekierowanie adresu URL) i wyjaśnić, jak go rozwiązać.
royfripple
Zaktualizowałem swoją odpowiedź, aby wyjaśnić, że otrzymałem ten sam błąd, zauważając, że podstawowy problem i rozwiązanie były różne. Wydaje mi się, że jest to poprawne, ponieważ inni mogą znaleźć to pytanie podczas wyszukiwania tego samego błędu. Jeśli uważasz, że ma to sens, rozważ zmianę głosu.
royfripple
Dziękuję Ci. Sprawia, że ​​wszystko jest wyraźniejsze, odwróciłem moją opinię
Done Data Solutions
Nie ma za co! I dzięki za poświęcenie czasu na jego ponowne sprawdzenie.
royfripple
2

Napotkałem ten sam problem i rozwiązałem go, wykonując poniższe proste kroki:

1) Pobierz InstallCert.java z Google

2) Skompiluj za pomocą javac InstallCert.java

3) Uruchom InstallCert.java, używając java InstallCert.java , z nazwą hosta i portem https, i naciśnij „1”, gdy poprosisz o wprowadzenie danych. Dodanie „localhost” jako zaufanego magazynu kluczy i wygenerowanie pliku o nazwie „jssecacerts”, jak poniżej:

java InstallCert localhost: 443

4) skopiuj plik jssecacerts do folderu $ JAVA_HOME / jre / lib / security

Główne źródło rozwiązania problemu tutaj:

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

Ankur jain
źródło
1

Rozwiązałem ten problem w systemie Windows Server 2016 z Javą 8, importując cert ze pkcs12sklepu do cacertsmagazynu kluczy.

Ścieżka do sklepu pkcs12:
C:\Apps\pkcs12.pfx

Ścieżka do cacerts Java:
C:\Program Files\Java\jre1.8.0_151\lib\security\cacerts

Ścieżka do keytool:
C:\Program Files\Java\jre1.8.0_151\bin

Po umieszczeniu w folderze z keytool w wierszu polecenia (jako administrator) polecenie importowania certyfikatu z pkcs12do cacertsjest następujące:
keytool -v -importkeystore -srckeystore C:\Apps\pkcs12.pfx -srcstoretype PKCS12 -destkeystore "C:\Program Files\Java\jre1.8.0_151\lib\security\cacerts" -deststoretype JKS

Zostaniesz poproszony o:
1. wprowadzenie docelowego hasła do pliku kluczy (hasło cacerts, domyślnie „changeit”)
2. wprowadź hasło źródłowego pliku kluczy (hasło pkcs12)


Aby zmiany odniosły skutek, zrestartuj serwer (lub ponownie uruchom JVM).

ognjenkl
źródło
1
Zastosowałem to podejście na komputerze Mac i po prostu zadziałało. Mój certyfikat został oczywiście samopodpisany i wygenerowany, aby zaimportować plik .pfx, który wygenerowałem na serwerze Windows ADFS. Korzystanie z Java 10 dla mojej aplikacji Dzięki
Shashikant Soni
0

Tutaj zwykle ten rodzaj wyjątku występuje, gdy występuje niezgodność w ścieżce PATH zaufanego certyfikatu. Sprawdź konfigurację lub ścieżkę, w której ten certyfikat serwera jest wymagany do bezpiecznej komunikacji.

ketan
źródło
Czy możesz mi powiedzieć dokładną konfigurację, w której mogę zainstalować certyfikat. Właściwie mam problem z tym, zainstalowałem certyfikat dotyczący tego problemu za pomocą keytool , działa to przez około 20-30 minut, a następnie serwer ponownie wydaje ten sam błąd. Proszę pomóż mi. Utknąłem w tym numerze przez 2 dni.
Deepak Gangore
Myślę, że certyfikat zmienia się co 20-30 minut
Vishwanath gowda k
Mam do czynienia z podobnym problemem, ale problemem jest: MOJA java wybierz domyślną lokalizację dla $ JAVA_HOME / lib / security / cacerts aplikacji Java, chociaż dostarczyłem -Djavax.net.ssl.trustStore = / myapp / app.jks Czy ktoś może mi pomóc na ten temat: stackoverflow.com/questions/33821785/…
Laxman G
0

Dla mnie pojawił się błąd certyfikatu, ponieważ miałem skrzypek działający w tle, co popsuło się certyfikatem. Działa jak proxy tak blisko, że ponownie uruchamia zaćmienie.

Atińska
źródło
ten sam problem dzieje się w zaćmieniu, nawet po zamknięciu wszystkich aplikacji
arvindwill
0

cele:

  1. użyj połączeń https
  2. zweryfikuj łańcuchy SSL
  3. nie zajmuj się cacertami
  4. dodaj certyfikat w czasie wykonywania
  5. nie trać certyfikatów z cacerts

Jak to zrobić:

  1. zdefiniuj własny magazyn kluczy
  2. umieść certyfikat w magazynie kluczy
  3. przedefiniuj domyślny kontekst SSL za pomocą naszej klasy niestandardowej
  4. ???
  5. zysk

Plik otoki mojego magazynu kluczy:

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

Ta klasa utworzy magazyn kluczy, jeśli to konieczne, i będzie w stanie zarządzać wewnątrz nim certyfikatami. Teraz klasa dla kontekstu 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;
    }
}

Ta klasa została utworzona jako singleton, ponieważ dozwolony jest tylko jeden domyślny kontekst SSL. Więc teraz użycie:

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

Być może nie będzie działać z tymi ustawieniami, ponieważ przechowuję plik certyfikatu w folderze zasobów, więc moja ścieżka nie jest bezwzględna. Ale ogólnie działa idealnie.

degr
źródło
1
To podwójne niewłaściwe użycie available()jest wyraźnie przestrzegane w jej własnym Javadoc.
Markiz Lorne
0

Jest to dodatek do odpowiedzi https://stackoverflow.com/a/36427118/1491414 . Dzięki @MagGGG

  • Upewnij się, że masz uprawnienia administratora
  • Proszę użyć podwójnych cudzysłowów dla ścieżki magazynu kluczy (-keystore C: \ Program Files (x86) \ Java \ jre1.6.0_22 \ lib \ security \ cacerts "), ponieważ w systemie operacyjnym Windows domyślną lokalizacją instalacji będą pliki programu, a otrzymasz błąd z powodu spacji między plikami programu.
Ganesa Vijayakumar
źródło
0

Naprawiłem to za pomocą poniższej metody-

  1. Skopiuj adres URL, który ma problem z połączeniem
  2. Przejdź do Android Studio-> Ustawienia-> Ustawienia HTTP
  3. W „Testuj połączenie” wklej ten adres URL i naciśnij OK
  4. Po kliknięciu OK, Android Studio poprosi o zaimportowanie certyfikatu tego adresu URL, zaimportowanie go
  5. Otóż ​​to. Nic więcej nie można zrobić, a problemu już nie ma. Nie trzeba też ponownie uruchamiać studia.
AndroDev
źródło
0

Gdy masz powyżej błąd związany z oprogramowaniem atlassian np. 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 '[email protected]' 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

możesz dodać certyfikaty do zaufanego magazynu kluczy (zmień brakujący_ca na prawidłową nazwę certyfikatu):

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

Jeśli zostaniesz poproszony o podanie hasła, wpisz changeiti potwierdźy

Następnie po prostu uruchom ponownie Jira.

Karol Murawski
źródło
0

Jeśli adres URL repozytorium działa również na HTTP, a bezpieczeństwo nie stanowi problemu, możesz przejść do settings.xml (często, ale nie zawsze, znajduje się w %USERPROFILE%/.m2) i zastąpić HTTPS HTTP dla <repository>i <pluginRepository>adresów URL.

Na przykład:

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

należy zastąpić następującym:

<repository>
    <snapshots>
        <enabled>false</enabled>
    </snapshots>
    <id>central</id>
    <name>libs-release</name>
    <url>https://<artifactory>/libs-release</url>
</repository>
ROMANIA_inżynier
źródło
0

Korzystałem z własnego magazynu zaufania zamiast JRE, przekazując arg -Djavax.net.ssl.trustStore=

Ten błąd pojawiał się niezależnie od certyfikatów w magazynie zaufanych certyfikatów. Problemem było dla mnie uporządkowanie właściwości przekazywanych na linii arg. Kiedy wstawiłem -Djavax.net.ssl.trustStore=& -Djavax.net.ssl.trustStorePassword= before -Dspring.config.location= & -jarargs, udało mi się pomyślnie wywołać moje połączenie przez https.

jasonoriordan
źródło
0

Jeśli używasz CloudFoundry i napotkasz problem z certyfikatem, musisz upewnić się, że ponownie wcisnąłeś słoik za pomocą usługi magazynu kluczy z certyfikatem. Po prostu cofnij powiązanie, powiązanie i ponowne uruchomienie nie będzie działać.

Smart Coder
źródło
0

Jeśli Twój host znajduje się za zaporą / proxy , użyj następującego polecenia w cmd:

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

Wymień <proxy_hostname>i <proxy_port>z serwera proxy HTTP, który jest skonfigurowany. Zamień na <remote_host_name:remote_ssl_port>jeden z hostów zdalnych (w zasadzie url) i port z problemem certyfikacji.

Weź ostatnią wydrukowaną treść certyfikatu i skopiuj ją (również skopiuj certyfikat początkowy i końcowy). Wklej go do pliku tekstowego i nadaj mu rozszerzenie .crt . Teraz zaimportuj ten certyfikat do cacerts za pomocą komendy java keytool i powinien on działać.

keytool -importcert -file <filename>.crt -alias randomaliasname -keystore %JAVA_HOME%/jre/lib/security/cacerts -storepass changeit
Aniket Warey
źródło
0

Spróbuj skopiować cacerts 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

Lucas Mendes Mota Da Fonseca
źródło
0

Jeśli ten problem występuje w kontenerze linux, gdy aplikacja Java próbuje komunikować się z inną aplikacją / witryną, to dlatego, że certyfikat został niepoprawnie zaimportowany do modułu równoważenia obciążenia. Aby zaimportować certyfikaty, należy wykonać sekwencję kroków, a jeśli nie zostaną wykonane poprawnie, pojawią się takie problemy

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

Po prawidłowym zaimportowaniu certyfikatów należy to zrobić. Nie trzeba majstrować przy jakichkolwiek certyfikatach JDK.

vsingh
źródło
0

Rozwiązałem go dla Intellij Idea Stoję przed tym problemem Althouh, zmieniam wiele miejsc, aby rozwiązać problem. Znalazłem rozwiązanie dla mnie. Kliknij prawym przyciskiem myszy swój projekt, zobaczysz Maven , po tym naciśnij Generuj źródła i aktualizuj foldery i ponownie importuj wprowadź opis zdjęcia tutaj

Zrobione.

java.nazif
źródło
0

Napotkałem ten sam problem, korzystałem z wersji 8.1.0-3, ale później użyłem wersji 9.2.1-0 i problem został rozwiązany bez żadnych ręcznych kroków. Samopodpisany certyfikat działał dobrze.

Darshil Shah
źródło