"PKIX path building failed failed" и "не удалось найти допустимый путь сертификации для запрошенной цели"

Я пытаюсь получить твиты с помощью библиотеки twitter4j для моего проекта java. Во время первого запуска я получил сообщение об ошибке sun.security.validator.ValidatorException и sun.security.provider.certpath.SunCertPathBuilderException. Затем я добавил твиттер-сертификат:

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

Но без успеха. Вот процедура получения твиттеров:

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

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

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

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

И вот ошибка:

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

Ответ 1

  • Перейдите к URL-адресу вашего браузера Firefox, нажмите цепочку сертификатов HTTPS (рядом с адресом URL). Нажмите "more info" > "security" > "show certificate" > "details" > "export..". Выберите имя и выберите тип файла example.cer. Теперь у вас есть файл с хранилищем ключей, и вы должны добавить его в свою JVM

  • Определить местоположение файлов cacerts, например. C:\Program Files (x86)\Java\jre1.6.0_22\lib\security\cacerts.

  • Затем импортируйте файл example.cer в cacerts в командной строке:

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

Вам будет задан пароль, по умолчанию - changeit

Перезапустите JVM/ПК.

Источник: http://magicmonster.com/kb/prg/java/ssl/pkix_path_building_failed.html

Ответ 2

После многих часов, пытаясь создать файлы сертификатов, чтобы моя установка на Java 6 работала с новым сертификатом twitter, я, наконец, наткнулся на невероятно простое решение, заложенное в комментарии на одной из досок объявлений. Просто скопируйте файл cacerts из установки Java 7 и перезапишите его в вашей версии Java 6. Наверное, лучше сначала сделать резервную копию файла cacerts, но тогда вы просто скопируете новый и BOOM! он просто работает.

Обратите внимание, что я фактически скопировал файл cacerts Windows на установку Linux, и он работал нормально.

Файл находится в jre/lib/security/cacerts как в старой, так и в новой установке Java jdk.

Надеюсь, что это спасет кого-то еще часы отягощения.

Ответ 3

Я наткнулся на эту проблему, которая потребовала много часов исследований для исправления, особенно с автогенерированными сертификатами, которые, в отличие от официальных, довольно сложны, и Java их не очень нравится.

Пожалуйста, проверьте следующую ссылку: Решите проблему с сертификатами в Java

В основном вам нужно добавить сертификат с сервера в сертификаты Java Home.

  • Создайте или получите свой сертификат и настройте Tomcat, чтобы использовать его в Servers.xml
  • Загрузите исходный код Java класса InstallCert и выполните его во время работы сервера, предоставив следующие аргументы server[:port]. Пароль не требуется, поскольку исходный пароль работает для сертификатов Java ( "changeit" ).
  • Программа будет подключаться к серверу, а Java будет генерировать исключение, она проанализирует сертификат, предоставленный сервером, и позволит вам создать файл jssecerts внутри каталога, в котором вы выполнили Программу (если выполняется из Eclipse then убедитесь, что вы настраиваете рабочий каталог в Run -> Configurations).
  • Вручную скопируйте этот файл в $JAVA_HOME/jre/lib/security

После выполнения этих шагов соединения с сертификатом больше не будут генерировать исключения в Java.

Следующий исходный код важен, и он исчез из (Sun) блогов Oracle, единственной страницы, на которую я нашел его, на ссылке, поэтому я прикрепляю ее в ответе для любой ссылки.

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

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

/**
 * Class used to add the server 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);
        }
    }
}

Ответ 4

Мой подход к интерфейсу:

  • Загрузить http://www.keystore-explorer.org/
  • Открыть $JAVA_HOME/jre/lib/security/cacerts
  • введите PW: changeit (может быть изменено на Mac)
  • Импортируйте ваш .crt файл

CMD-Line:

  • keytool -importcert -file jetty.crt -alias jetty -keystore $JAVA_HOME/jre/lib/security/cacerts
  • введите PW: changeit (может быть изменено на Mac)

Ответ 5

1. Проверьте сертификат

Попробуйте загрузить целевой URL-адрес в браузере и просмотреть сертификат сайта (обычно он доступен по значку со знаком блокировки. Он находится слева или справа от адресной строки браузера), независимо от того, истек ли он или не был доверен по другой причине.

2. Установите последние версии JRE и JDK

Новые версии обычно поставляются с обновленным набором доверенных сертификатов.

Также, если это возможно, удалите старые версии. Это сделает ошибки неверной конфигурации явными.

3. Проверьте свою конфигурацию:

  • Проверьте, куда указывает ваша переменная окружения JAVA_HOME.
  • Проверьте, какую версию Java вы используете для запуска программы. В IntelliJ проверьте:
    • Файл → Структура проекта... → Настройки проекта → Проект → Project SDK:
    • Файл → Структура проекта... → Настройки платформы → SDK

4. Скопируйте весь склад ключей из новой версии Java

Если вы разрабатываете с использованием JDK, отличного от последнего доступного, попробуйте заменить файл %JAVA_HOME%/jre/lib/security/cacerts новым файлом из последней установленной JRE (сначала создайте резервную копию), как предлагает @jeremy-goodell. в своем ответе

5. Добавьте сертификат в ваше хранилище ключей

Если ничто из перечисленного не решает вашу проблему, используйте keytool для сохранения сертификатов в хранилище ключей Java:

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

Файл с сертификатом можно получить из браузера, как подсказывает @MagGGG в своем ответе.

Примечание 1: вам может потребоваться повторить это для каждого сертификата в цепочке к сертификату вашего сайта. Начните с корневого.

Примечание 2: <alias_name> должно быть уникальным среди ключей в хранилище, иначе keytool выдаст ошибку.

Чтобы получить список всех сертификатов в магазине, вы можете запустить:

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

В случае, если что-то пойдет не так, это поможет вам удалить сертификат из магазина:

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

Ответ 6

У меня была немного другая ситуация, когда в моей системе присутствовали как JDK, так и JRE 1.8.0_112.

Я импортировал новые сертификаты CA в [JDK_FOLDER]\jre\lib\security\cacerts с помощью уже известной команды:

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

Тем не менее, я по-прежнему получал ошибку с ошибкой PKIX.

Я добавил информацию об отладке в CLI java, используя java -Djavax.net.debug=all ... > debug.log. В файле debug.log строка, начинающаяся с trustStore: фактически указывает на хранилище cacerts, найденное в [JRE_FOLDER]\lib\security\cacerts.

В моем случае решение заключалось в том, чтобы скопировать файл cacerts, используемый JDK (с добавлением новых CA), по сравнению с тем, который использовался JRE, и это устранило проблему.

Ответ 7

Я хотел импортировать сертификат для smtp.gmail.com

Только решение для меня было 1. Введите команду для просмотра этого сертификата

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

  1. Скопируйте и сохраните строки между "----- BEGIN CERTIFICATE -----" и "----- END CERTIFICATE -----" в файл gmail.cer

  2. Run

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

  3. Введите пароль chageit

  4. Нажмите "Да", чтобы импортировать сертификат

  5. Перезапустите java

теперь запустите команду, и вам хорошо идти

Ответ 8

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

Он используется для перехода к проверке сертификата.

Ответ 9

История вопроса:

Я получаю следующую ошибку, когда пытаюсь запустить mvn clean install в моем проекте и с помощью опции очистки и сборки среды IDE Netbeans. Эта проблема возникает из-за того, что сертификат недоступен при загрузке через IDE NET/через командную строку, но позволяет загружать файлы через браузер.

Ошибка:

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  

Разрешение:

1. Загрузите сертификат указанного URL:

  • Запустите IE с помощью "Запуск от имени администратора" (иначе мы не сможем скачать сертификат)
  • Введите URL-адрес в IE-> https://url/local-repo (в моем случае этот URL-адрес имел ненадежный сертификат enter image description here.)
  • Загрузите сертификат, нажав "Ошибка сертификата" → просмотреть сертификат
  • Выберите вкладку "Сведения" → "Копировать в файл" → "Далее" → "Выбрать" кодированный двоичный код DER X.509 (.CER).
  • сохраните сертификат в каком-либо месте, например: c: /user/sheldon/desktop/product.cer
  • Congrats! Вы успешно загрузили сертификат для сайта

2. Теперь установите хранилище ключей, чтобы исправить проблему.

  • Выполните команду keytool, чтобы добавить загруженное хранилище ключей в существующий файл сертификата.
  • Команда: Команда ниже в папке bin jdk (JAVA_HOME).

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

  • Вам будет предложено ввести пароль. Введите пароль хранилища ключей: введите "changeit" еще раз для "Доверять этому сертификату? [No]:", введите "yes"

Примеры команд командной строки/вывод:

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! Теперь вы должны были избавиться от ошибки "Ошибка построения пути PKIX: sun.security.provider.certpath.SunCertPathBuilderException" в вашей среде IDE Netbeans.

Ответ 10

Причина, по которой мы получаем вышеупомянутую ошибку, состоит в том, что JDK связывается с большим количеством доверенных сертификатов Центра сертификации (CA) в файл с именем 'cacerts, но этот файл не имеет понятия о нашем самоподписанном сертификате. Другими словами, файл cacerts не имеет импортированного нашего самозаверяющего сертификата и, следовательно, не обрабатывает его как доверенный объект, и, следовательно, выдает вышеуказанную ошибку.

Как исправить вышеуказанную ошибку

Чтобы исправить вышеуказанную ошибку, все, что нам нужно, это импортировать самоподписанный сертификат в файл cacerts.

Сначала найдите файл cacerts. Нам нужно будет узнать местоположение JDK. Если вы запускаете свое приложение через одну из сред IDE, например Eclipse или IntelliJ Idea, перейдите в настройки проекта и выясните, где находится JDK. Например, в Mac OS типичное расположение файла cacerts будет в этом месте /Library/Java/JavaVirtualMachines/{{JDK_version}}/Contents/Home/jre/lib/security на компьютере с Windows, оно будет находиться в {{Installation_directory} }/{{JDK_version}}/JRE/Library/безопасность

Как только вы нашли файл cacerts, теперь нам нужно импортировать наш самоподписанный сертификат в этот файл cacerts. Проверьте последнюю статью, если вы не знаете, как правильно создать самозаверяющий сертификат.

Если у вас нет файла сертификата (.crt) и у вас просто есть файл .jks, вы можете сгенерировать файл .crt с помощью следующей команды. Если у вас уже есть файл .crt/.pem, вы можете проигнорировать следующую команду

## Для генерации сертификата из хранилища ключей (файл .jks) ####

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

Выше шаг будет генерировать файл с именем selfsigned.crt.Now Импортировать сертификат в cacerts

Теперь добавьте сертификат в JRE/lib/security/cacerts (trustore)
keytool -importcert -file selfsigned.crt -alias selfsigned -keystore {{cacerts path}}

например

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

Вот и все, перезапустите приложение, и оно должно работать нормально. Если это все еще не работает и получите исключение рукопожатия SSL. Это, вероятно, означает, что вы используете другой домен, зарегистрированный в сертификате.

Ссылка с подробным объяснением и пошаговым разрешением здесь.

Ответ 11

Это не ответ на Твиттер, но это вопрос, который возникает при поиске этой ошибки. Если ваша система получает эту ошибку при подключении к веб-сайту, у которого появляется действительный сертификат при просмотре в веб-браузере, это, вероятно, означает , что на веб-сайте имеется неполная цепочка сертификатов,

Для краткого изложения проблемы: органы сертификации не используют свой корневой сертификат для подписи только какого-либо старого сертификата. Вместо этого они (обычно) подписывают промежуточные сертификаты, которые также имеют установленный флаг центра сертификации (то есть имеют право подписывать сертификаты). Затем, когда вы покупаете сертификат из центра сертификации, они подписывают вашу CSR с одним из этих промежуточных сертификатов.

В вашем хранилище доверия Java скорее всего есть только Root Cert, а не промежуточные.

Неправильно сконфигурированный сайт может вернуть только подписанный сертификат. Проблема: он был подписан с промежуточным сертификатом, который не находится в вашем магазине доверия. Браузеры справятся с этой проблемой, загрузив или используя промежуточный сертификат с кешем; это максимизирует совместимость с сайтом. Однако Java и инструменты, такие как OpenSSL, не будут. И это вызовет ошибку в вопросе.

Вы можете проверить это подозрение, используя Qualys SSL Test. Если вы запустите это на сайте, и он говорит

Эта цепочка сертификатов сервера не завершена.

что подтверждает это. Вы также можете увидеть это, посмотрев пути сертификации и увидев текст "Дополнительная загрузка".

Как это исправить: администратору сервера необходимо настроить веб-сервер для возврата промежуточных сертификатов. Например, для Comodo это пригодится файл .ca-bundle. Например, в конфигурации Apache с mod_ssl вы должны использовать настройку конфигурации SSLCertificateChainFile. Для nginx вам необходимо объединить промежуточные сертификаты и подписанный сертификат и использовать их в конфигурации SSL-сертификата. Вы можете найти больше, выполнив поиск "незавершенной цепи сертификатов" в Интернете.

Ответ 12

Добавление cacerts не помогло мне. После включения журнала с флагом -Djavax.net.debug=all, он узнал java-чтение из jssecacerts.

Импорт в jssecacerts наконец-то завершился.

Ответ 13

Я столкнулся с этим вопросом, пытаясь установить плагин Cucumber-Eclipse в Eclipse через сайт обновлений. Я получил ту же ошибку 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

Хотя некоторые из других ответов являются подходящими и полезными для данного вопроса в данной ситуации, они тем не менее бесполезны и вводят в заблуждение для моей проблемы.

В моем случае проблема заключалась в том, что URL-адрес, указанный для сайта обновлений:

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

Однако при навигации по нему через браузер он перенаправляется (обратите внимание на добавленный ".github" ):

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

Таким образом, разрешение заключается в том, чтобы просто использовать перенаправленную версию URL сайта обновления при добавлении сайта обновления в eclipse.

Ответ 14

Я столкнулся с той же проблемой и решил ее, используя следующие простые шаги:

1) Загрузите InstallCert.java с Google

2) Скомпилируйте его, используя javac InstallCert.java

3) Запустите InstallCert.java, используя java InstallCert.java, с именем хоста и https портом, и нажмите "1" при запросе ввода. Он добавит "localhost" в качестве доверенного хранилища ключей и сгенерирует файл с именем "jssecacerts", как показано ниже:

java InstallCert localhost: 443

4) скопируйте jssecacerts в папку $ JAVA_HOME/jre/lib/security

Основной источник для решения проблемы здесь:

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

Ответ 15

Здесь обычно такое исключение возникает, когда существует несоответствие в PATH доверенного сертификата. Проверьте конфигурацию или путь, где требуется сертификат сервера для защищенной связи.

Ответ 16

У меня такая же проблема на ubuntu 15.10. Попробуйте загрузить плагин локально, например. https://github.com/lmenezes/elasticsearch-kopf/archive/master.zip и установите с помощью этой команды:

sudo /usr/share/elasticsearch/bin/plugin install file:/home/dev/Downloads/elasticsearch-kopf-master.zip

Путь может отличаться в зависимости от вашей среды.

С уважением.

Ответ 17

Для меня возникла ошибка сертификата, потому что у меня был скрипач, работающий в фоновом режиме, и это испортило сертификат. Он действует как прокси-сервер так близко и перезапускает eclipse.

Ответ 18

Это дополнение к ответу fooobar.com/questions/41702/.... Спасибо @MagGGG

  • Пожалуйста, убедитесь, что у вас есть разрешение администратора.
  • Используйте двойные кавычки для пути к хранилищу ключей (-keystore C:\Program Files (x86)\Java\jre1.6.0_22\lib\security\cacerts "), поскольку в ОС Windows по умолчанию устанавливается местоположение файлов программы и вы получите сообщение об ошибке из-за пробелов между программными файлами.

Ответ 19

Я исправил это, используя ниже method-

  1. Скопируйте URL, который имеет проблему с подключением
  2. Зайдите в Android Studio-> Настройки-> Настройки Http
  3. В "Test Connection" вставьте этот URL и нажмите ОК
  4. При нажатии ОК, Android Studio попросит импортировать сертификат этого URL, импортировать его
  5. Это. Больше ничего не поделаешь, и моя проблема исчезла. Нет необходимости перезагружать студию.

Ответ 20

Если у вас есть выше ошибка с Atlassian Software 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 '[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

Вы можете добавить сертификаты к этому доверенному хранилищу ключей (замените missing_ca на правильное имя сертификата):

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

Если запрашивается пароль, changeit и подтвердите y

После этого просто перезапустите Jira.

Ответ 21

Если ваш URL-адрес хранилища также работает по протоколу HTTP и безопасность не представляет проблемы, вы можете перейти к файлу settings.xml (часто, но не всегда, в %USERPROFILE%/.m2) и заменить HTTPS на HTTP для <repository> и <pluginRepository> URL-адреса.

Например, это:

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

следует заменить на это:

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

Ответ 22

Я использовал свое собственное хранилище доверия, а не JRE, передавая arg -Djavax.net.ssl.trustStore=

Я получал эту ошибку независимо от сертификатов в складах доверенных сертификатов. Для меня проблемой было упорядочение свойств, передаваемых по строке arg. Когда я поставил -Djavax.net.ssl.trustStore= & -Djavax.net.ssl.trustStorePassword= до -Dspring.config.location= & -jar args, я смог успешно вызвать мой вызов по отдыху через https.

Ответ 23

Если вы используете CloudFoundry и столкнулись с проблемой сертификата, вам нужно будет убедиться, что вы снова подтолкнули банку со службой хранилища ключей с сертификатом в нем. Просто отсоединить, связать и перезапустить не получится.

Ответ 24

Попробуйте скопировать Java Cacerts:

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

Ответ 25

Если вы видите эту проблему в контейнере Linux, когда приложение Java пытается связаться с другим приложением/сайтом, это происходит из-за того, что сертификат был неправильно импортирован в балансировщик нагрузки. Существует последовательность шагов, которые необходимо выполнить для импорта сертификатов, и если вы все сделаете неправильно, вы увидите такие проблемы, как

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

Как только сертификаты импортированы правильно, это должно быть сделано. Нет необходимости возиться с какими-либо сертификатами JDK.

Ответ 26

цели:

  • использовать соединения https
  • проверить цепочки SSL
  • не обрабатывать cacerts
  • добавить сертификат во время выполнения
  • не потерять сертификаты из cacerts

Как это сделать:

  • определить собственное хранилище ключей
  • поместить сертификат в хранилище ключей
  • переопределить контекст SSL по умолчанию с нашим пользовательским классом
  • ???
  • прибыль

Файл оболочки My Keystore:

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

Этот класс будет создавать хранилище ключей, если это необходимо, и сможет управлять сертификатами внутри него. Теперь класс для контекста 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;
    }
}

Этот класс сделан как singleton, потому что разрешен только один контекст defaultSSL. Итак, теперь использование:

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

Возможно, он не будет работать с этими настройками, потому что я сохраняю файл сертификата внутри папки ресурсов, поэтому мой путь не является абсолютным. Но в целом, он отлично работает.

Ответ 27

Если ваш хост находится за брандмауэром/прокси, используйте следующую команду в cmd:

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

Замените <proxy_hostname> и <proxy_port> на настроенный прокси-сервер HTTP. Замените <remote_host_name:remote_ssl_port> одним из удаленных хостов (в основном, url) и порта, имеющих проблему с сертификацией.

Возьмите последний напечатанный контент сертификата и скопируйте его (также скопируйте начало и конец сертификата). Вставьте его в текстовый файл и дайте ему расширение .crt. Теперь импортируйте этот сертификат в cacerts с помощью команды java keytool, и он должен работать.

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