Вопрос-ответ

"PKIX path building failed" and "unable to find valid certification path to requested target"

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

Я пытаюсь получать твиты, используя библиотеку twitter4j для моего java-проекта, который использует under the covers java.net.HttpURLConnection (как видно из трассировки стека). При первом запуске я получил сообщение об ошибке с сертификатом sun.security.validator.ValidatorException и sun.security.provider.certpath.SunCertPathBuilderException. Затем я добавил сертификат Twitter с помощью:

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

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

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

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

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

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

И вот ошибка:

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

  1. Перейдите по URL-адресу в вашем браузере:


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

  • chrome - щелкните значок сайта слева, чтобы обратиться в адресной строке, выберите "Сертификат" -> "Подробности" -> "Экспорт" и сохраните в формате "Двоичный файл с Der-кодировкой, единый сертификат".


  1. Теперь у вас есть файл в хранилище ключей, и вы должны добавить его в свою JVM. Определите расположение файлов cacerts, например. C:\Program Files (x86)\Java\jre1.6.0_22\lib\security\cacerts.



  2. Затем импортируйте example.cer файл в cacerts в командной строке (может потребоваться командная строка администратора).:



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

У вас будет запрошен пароль, который по умолчанию равен changeit

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

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

Ответ 2

После многих часов попыток создать файлы сертификатов, чтобы моя установка Java 6 работала с новыми сертификатами Twitter, я, наконец, наткнулся на невероятно простое решение, скрытое в комментарии на одной из досок объявлений. Просто скопируйте файл cacerts из установки Java 7 и перезапишите файл в вашей установке Java 6. Вероятно, лучше всего сначала сделать резервную копию файла cacerts, но затем вы просто копируете новый и БУМ! это просто работает.

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

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

Надеюсь, это избавит кого-то еще от нескольких часов раздражения.

Ответ 3

МОЙ подход к пользовательскому интерфейсу:


  1. Загрузите keystore Explorer отсюда

  2. Откройте $JAVA_HOME/jre /lib /security /cacerts

  3. введите PW: changeit (Может быть changeme на Mac)

  4. Импортируйте ваш файл .crt

CMD-строка:


  1. keytool -importcert -file jetty.crt -alias jetty -keystore $JAVA_HOME/jre/lib/security/cacerts

  2. введите PW: changeit (Может быть изменен на Mac)

Ответ 4

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

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

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

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

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

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


  • Проверьте, на что указывает ваша переменная среды JAVA_HOME.

  • Проверьте, какую версию java вы используете для запуска программы. В IntelliJ проверьте:

    • Файл -> Структура проекта... -> Настройки проекта -> Проект -> Project SDK:

    • Файл -> Структура проекта... -> Настройки платформы -> SDKs


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
java