Error pkix path building failed

The content on this page relates to platforms which are not supported. Consequently, Atlassian Support cannot guarantee providing any support for it. Please be aware that this material is provided for your information only and using it is done so at your own risk.

The content on this page relates to platforms which are not supported. Consequently, Atlassian Support cannot guarantee providing any support for it. Please be aware that this material is provided for your information only and using it is done so at your own risk.

Problem

Attempting to access applications or websites that are encrypted with SSL (for example HTTPS, LDAPS, IMAPS) throws an exception and the connection is refused. This can happen when attempting to establish a secure connection to any of the following:

  • Active Directory server, JIRA User Server or Crowd
  • Mail server 
  • Another Atlassian application using Application Links
  • Atlassian Marketplace
  • Atlassian Migration Service

For example, the following error appears in the UI when Using the JIRA Issues Macro:

Error rendering macro: java.io.IOException: Could not download: https://siteURL/jira/secure/IssueNavigator.jspa?view=rss&&type=12&type=4&type=3&pid=10081&resolution=1&fixfor=10348&sorter/field=issuekey&sorter/order=DESC&sorter/field=priority&sorter/order=DESC&tempMax=100&reset=true&decorator=none

While the following appears in the logs:

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

Diagnosis

Use SSL Poke to verify connectivity

Try the Java class SSLPoke to see if your truststore contains the right certificates. This will let you connect to a SSL service, send a byte of input, and watch the output.

  1. Download SSLPoke.class
  2. Execute the class as per the below, changing the URL and port appropriately. Take care that you are running the same Java your application (Confluence, Jira, etc.) is running with. If you used the installer you will need to use <application-home>/jre/java

    $JAVA_HOME/bin/java SSLPoke jira.example.com 443

A failed connection would produce the below:

$JAVA_HOME/bin/java SSLPoke jira.example.com 443
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(PKIXValidator.java:387)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
	at sun.security.validator.Validator.validate(Validator.java:260)
	at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1351)
	at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:156)
	at sun.security.ssl.Handshaker.processLoop(Handshaker.java:925)
	at sun.security.ssl.Handshaker.process_record(Handshaker.java:860)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1043)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1343)
	at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:728)
	at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
	at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:138)
	at SSLPoke.main(SSLPoke.java:31)
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:145)
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:131)
	at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
	... 15 more

(warning) To get more details from a failed connection, use the -Djavax.net.debug=ssl parameter. For example: 

java -Djavax.net.debug=ssl SSLPoke jira.example.com 443

A successful connection would look like this:

$JAVA_HOME/bin/java SSLPoke jira.example.com 443
Successfully connected

If -Djavax.net.ssl.trustStore is present in your JVM arguments, Java will use the truststore configured instead of the default (cacerts).  You can verify whether the -Djavax.net.ssl.trustStore parameter is causing problems by running the SSLPoke test using the same JVM argument which will execute SSLPoke using your custom truststore. For example:

$JAVA_HOME/bin/java -Djavax.net.ssl.trustStore=/my/custom/truststore -Djavax.net.debug=ssl SSLPoke jira.example.com 443

If this fails (confirming that the truststore doesn’t contain the appropriate certificates), the certificate will need to be imported into your defined custom truststore using the instructions in Connecting to SSL Services.

Cause

Whenever Java attempts to connect to another application over SSL (e.g.: HTTPS, IMAPS, LDAPS), it will only be able to connect to applications it can trust.  The way trust is handled in Java is that you have a truststore (typically $JAVA_HOME/lib/security/cacerts). The truststore contains a list of all known Certificate Authority (CA) certificates, and Java will only trust certificates that are signed by one of those CAs or public certificates that exist within that truststore. For example, if we look at the certificate for Atlassian, we can see that the *.atlassian.com certificate has been signed by the intermediate certificates, DigiCert High Assurance EV Root CA and DigiCert High Assurance CA-3. These intermediate certificates have been signed by the root  Entrust.net Secure Server CA :

These three certificates combined are referred to as the certificate chain, and, as they are all within the Java truststore (cacerts), Java will trust any certificates signed by them (in this case, *.atlassian.com). Alternatively, if the *. atlassian.com  certificate had been in the truststore, Java would also trust that site.

This problem is therefore caused by a certificate that is self-signed (a CA did not sign it) or a certificate chain that does not exist within the Java truststore. Java does not trust the certificate and fails to connect to the application.

(info) For details on how to examine a website’s certificate chain, see the section, View a certificate, in Secure Website Certificate.

Resolution

  1. Make sure you have imported the public certificate of the target instance into the truststore according to the Connecting to SSL Services instructions.
  2. Make sure any certificates have been imported into the correct truststore; you may have multiple JRE/JDKs. See Installing Java for this.
  3. Check to see that the correct truststore is in use. If -Djavax.net.ssl.trustStore has been configured, it will override the location of the default truststore, which will need to be checked.
  4. If this error results while integrating with an LDAP server over LDAPS and there is more than one LDAP server, then deselect the Follow referrals option within the LDAP user directory configuration per Connecting to and LDAP Directory.  Optionally, import the SSL certificates from the other LDAP servers into the Confluence truststore.
  5. Check if your Anti Virus tool has «SSL Scanning» blocking SSL/TLS. If it does, disable this feature or set exceptions for the target addresses (check the product documentation to see if this is possible.)
  6. If connecting to a mail server, such as Exchange, ensure authentication allows plain text.
  7. Verify that the target server is configured to serve SSL correctly. This can be done with the SSL Server Test tool.
  8. If all else fails, your truststore might be out of date. Upgrade Java to the latest version supported by your application.

Important

Since the truststore only gets read once when the JVM is initialized, please restart the source application service after importing the new certificate(s).

More on SSL Poke

Atlassian’s SSL Poke source code can be found here.

You can find forked versions of SSL Poke in the community with support for extra features like Java 11, Proxy, etc.

Good examples:

  • https://github.com/gebi/sslpoke
  • https://gist.github.com/bric3/4ac8d5184fdc80c869c70444e591d3de

The article presents the steps to import required certificates and enable Java application to connect to Azure SQL DB/Managed Instance. If required certificates are missing on client machine when connecting via AAD authentication, a similar error will be prompted in the application logs:

«SQLServerException: Failed to authenticate the user in Active Directory (Authentication=ActiveDirectoryPassword).
Caused by: ExecutionException: mssql_shaded.com.microsoft.aad.adal4j.AuthenticationException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Caused by: AuthenticationException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target. «

This is an issue in Java Certificate Store. As a quick workaround, if you enable TrustServerCertificate=True in the connection string, the connection from JDBC succeeds. When TrustServerCertificate is set to true, the transport layer will use SSL to encrypt the channel and bypass walking the certificate chain to validate trust. If TrustServerCertificate is set to true and encryption is turned on, the encryption level specified on the server will be used even if Encrypt is set to false. The connection will fail otherwise. However, for security considerations, it is not recommended to bypass the certificate validation. Hence, to address the issue, follow the steps below to change the connection string and import the required certificates. 

  • Change the connection string to point to the Java certificate path

    String connectionUrl =  «jdbc:sqlserver://localhost:1433;» + 
        «databaseName=AdventureWorks;integratedSecurity=true;» + 
        «encrypt=true; trustServerCertificate=false;» + 
        «trustStore= C:Program FilesJavajdk-14.0.2libcacert;trustStorePassword=changeit»;

  • Import all the certificates mentioned in this document.

    Note: To import above certificates into the keystore cacerts, please use below command and please note you must mention truststore and truststore password in the connection string to successfully connect.  

Steps to import missing certificates in Java Certificate Store

Download all the certs from here, store them in a location on client host and then use keytool utility to import these certificates into the truststore. Please follow the below steps:

  • Save all the certificates from the above MS doc.
  • Keytool utility is in the bin folder of your default Java location (C:Program FilesJavajdk-14.0.2bin). You need to use command prompt to navigate to that location.
  • Then you can use the keytool command to import the certificate previously saved. 
  • When prompted for password insert the key in the password as “changeit

Example of commands:

keytool -importcert -trustcacerts -alias TLS1 -file «C:UsersDocumentsMicrosoft RSA TLS CA 01.crt» -keystore «C:Program FilesJavajdk-14.0.2libsecuritycacerts»

keytool -importcert -trustcacerts -alias TLS2 -file «C:UsersDocumentsMicrosoft RSA TLS CA 02.crt» -keystore «C:Program FilesJavajdk-14.0.2libsecuritycacerts»

Certificate was added to keystore.


0 Flares



Twitter


0








Facebook


0








Google+


0








LinkedIn


0








Email









Filament.io






0 Flares


×

How To Fix Error : sun.security.validator.ValidatorException: PKIX path building failed:

sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

You could get the error “PKIX path building failed” validation error when working on a client that works with an SSL enabled server running in https protocol. This article focuses on detecting the root cause of the error and on how to fix the issue.
There are other similar issues related the SSL certificates. One of the common situation is the missing certificate in trust store. In that case you may see the following error message.

Caused by: java.security.cert.CertificateException: No name matching localhost found at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:210) at sun.security.util.HostnameChecker.match(HostnameChecker.java:77)

See the following article to read more about the above error and its solution.

    How to Fix : java.security.cert.CertificateException: No name matching localhost found

Table of Contents

  • What is PKIX?
  • How to Detect PKIX Path Building Failed Error?
  • Unable to Find Valid Certification Path to Requested Target: Possible Reason For The Error
  • Fix for PKIX path building failed Error:sun.security.provider.certpath.SunCertPathBuilderException
  • References

The first part of the error, “javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: “,  indicates the type of error and the second part of the error message “sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target” gives an indication on what exactly went wrong.
Before diving into the cause and solution let us get some general knowledge 🙂
java pkix path building validation

What is PKIX?

PKIX is Public-Key Infrastructure X.509. PKIX is public key infrastructure standards based on X.509 protocol. X.509 is an ITU-T cryptography standard for a public key infrastructure (PKI) and Privilege Management Infrastructure (PMI). Read references for more details on The PKIX (Public-Key Infrastructure X.509) Working Group (PKIX-WG).

PKIX path building failed : sun.security.validator.ValidatorException

This error is one of the many SSL related errors you may experience when you start developing applications those communicates securely. This happens during one of the SSL Handshake phase. This exception is of type javax.net.ssl.SSLHandshakeException,  which indicates that the client and server could not negotiate the desired level of security. The connection is no longer usable.
The complete exception message is below:

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

How to Detect PKIX Path Building Failed Error?

Even though this is a common exception while connecting a service over HTTPS,  identifying the exact problem without proper debugging configuration is difficult. Unless you enable the SSL handshake debug mode (Java VM parameter -Djavax.net.debug=ssl:handshake) you will not be able to identify the root cause. Without SSL debug enabled you most likely will see the following error.

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:352)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:572)

The above message is more generic and in most cases will not give you the root cause of the issue. Once you enable SSL handshake debug mode you will see the following exception trace:

 http-localhost/127.0.0.1:8443-1, SEND TLSv1 ALERT: fatal, description = certificate_unknown
http-localhost/127.0.0.1:8443-1, WRITE: TLSv1 Alert, length = 2
http-localhost/127.0.0.1:8443-1, called closeSocket()
http-localhost/127.0.0.1:8443-1, 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
http-localhost/127.0.0.1:8443-1, called close()
http-localhost/127.0.0.1:8443-1, called closeInternal(true)

The above error indicates a missing trusted certificate in the trusted Java  store. Some other cases where,  you already have the certificate but there is a problem with its validity, you may see the following error (“timestamp check failed“).

handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: timestamp check failed.

We will be addressing the first scenario in which there is no certificate available (certificate_unknown).

Unable to Find Valid Certification Path to Requested Target: Possible Reason For The Error

If we look at the phase of the SSL handshake we’re in, we can see that we’ve already sent our client certificate and finishing up the handshake when we receive this error.

2015-02-04 21:59:33,002 INFO  [stdout] (http-localhost/127.0.0.1:8443-2) -  - *** ServerHelloDone
http-localhost/127.0.0.1:8443-2, WRITE: TLSv1 Handshake, length = 865
http-localhost/127.0.0.1:8443-1, READ: TLSv1 Handshake, length = 865
*** ServerHello, TLSv1
RandomCookie:  GMT: 1406265764 bytes = { 30, 87, 196, 168, 159, 159, 7, 254, 62, 168, 199, 80, 108, 117, 48, 3, 113, 72, 1, 226, 31, 195, 238, 86, 88, 192, 96, 94 }
Session ID:  {84, 210, 234, 164, 204, 121, 25, 56, 166, 145, 81, 180, 26, 103, 98, 72, 207, 54, 246, 139, 136, 17, 1, 140, 50, 131, 195, 18, 157, 80, 142, 4}
Cipher Suite: SSL_RSA_WITH_RC4_128_MD5
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: 
***
%% Created:  [Session-9, SSL_RSA_WITH_RC4_128_MD5]
** SSL_RSA_WITH_RC4_128_MD5
*** Certificate chain
Version: V3
Subject: CN=************************************
Signature Algorithm: SHA1withRSA, OID = *********************
Key:  Sun RSA public key, 2048 bits
.................................................
...................................................
***
SEND TLSv1 ALERT:  fatal, description = certificate_unknown
WRITE: TLSv1 Alert, length = 2
READ: TLSv1 Alert, length = 2
called closeSocket()
RECV TLSv1 ALERT:  fatal, certificate_unknown
called closeSocket()
handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
handling exception: 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

The above error stack trace is actually helpful. It says that “unable to find valid certification path to requested target“. This means that the certificate the server certificate is not issued by certification authority, but a self signed or issued by a private CMS. If the certificate is issued by a trusted authority (VeriSign etc) the error will not happen.

Fix for PKIX path building failed Error:sun.security.provider.certpath.SunCertPathBuilderException

All you need to do to fix this error is to add the server certificate to your trusted Java key store. First You need to download the document from the server.

To download: access the URL of the service from any browser.You will get a certificate related warning message. Click on view certificate and then Install certificate. You can export the certificate from browser to some location in hard drive (In IE go to Tools->’Internet Options’ ->Content->Certificates).

Once you have the certificate in your hard drive you can import it to the Java trust store. To import the certificate to the trusted Java key store, you can use the java ‘keytool‘ tool.
Use keytool command as follows to import the certificate to JRE.

keytool -import -alias _alias_name_ -keystore ..libsecuritycacerts -file _path_to_cer_file

It will ask for a password. By default the password is “changeit”. If the password is different you may not be able to import the certificate.
Note: You can also use the installcert java program from here.
Once completed restart/re-run your client application. You will be able to see successful SSL handshakes.

References:

  1. X.509 Public-key and attribute certificate frameworks
  2. Internet X.509 Public Key Infrastructure Certificate and CRL Profile RFC 2459
  3. Import the Certificate as a Trusted Certificate 

Incoming search terms:

  • pkix path building failed
  • pkix validation failed
  • PKIXPathBuildingFailed(Validation):sun security validator ValidatorException
  • sun security validator ValidatorException: PKIX path building failed: sun security provider certpath SunCertPathBuilderException: unable to find valid certification path to requested target
  • https://java globinch com/enterprise-java/security/pkix-path-building-failed-validation-sun-security-validatorexception/
  • PKIX path building failed: sun security provider certpath SunCertPathBuilderException: unable to find valid certification path to requested target
  • feign RetryableException: PKIX path building failed: sun security provider certpath SunCertPathBuilderException:
  • pkix path validation failed: java security cert certpathvalidatorexception: validity check failed
  • dbviewer download driver javax net ssl SSLHandshakeException:PKIX
  • Couldnt download vanilla jar! sun security validator ValidatorException: PKIX path building failed: sun security provider certpath SunCertPathBuilderException: unable to find valid certification path to requested target


0 Flares



Twitter


0








Facebook


0








Google+


0








LinkedIn


0








Email









Filament.io






0 Flares


×

Когда люди говорят «API тесты«, они обычно имеют в виду API, предоставляемый поверх протоколов HTTP либо HTTPs. Так сложилось, что упомянутые протоколы в подавляющем большинстве случаев используются при реализации архитектуры REST, а также, для реализации веб-сервисов, работающих по протоколу SOAP. В то время как простой HTTP обычно не вызывает никаких проблем, его ssl-расширение требует более сложного подхода и привлечения таких артефактов как «ключи» и «сертификаты». Некорректная конфигурация соединения в таких случаях часто приводит к падениям тестов в результате невозможности проверить валидность сертификата, возвращаемого тестовым сервером. В этой статье мы взглянем на такую проблему и узнаем как её решать.

Возможно вы видели сообщение об ошибке вида «PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target». Если да, значит вы нашли нужную статью.

В нашем примере мы создадим вызов ендпоинта «https://webelement.click», используя базовый инструментарий, входящий в поставку Java SDK (пакет java.net.*). Этот вызов скорее всего не будет успешным по причине невозможности валидации предоставляемого сервером сертификата. После этого мы сконфигурируем наш кастомный trust store (чуть позже я объясню что это такое) и научим наш код его использовать. Также мы рассмотрим подход при котором созданный нами trust store станет частью нашего тестового проекта, что сделает тесты более независимыми от среды исполнения.

Итак, вот модель наших API-тестов, которые пытаются осуществить вызов ендпоинта с использованием Secure Socket Layer (также известным под именем Transport Layer Security) протокола.

package click.webelement.https;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

public class ApiWithSSL {

    public static void main(String[] args) {

        try {
            HttpURLConnection connection = (HttpURLConnection) new URL("https://webelement.click").openConnection();
            int responseCode = connection.getResponseCode();
            if(responseCode != 200){
                System.out.println("Test failed with actual status code: " + responseCode);
            }else{
                System.out.println("Test passed");
            }
        } catch (IOException e) {
            System.out.println("Test failed with exception: " + e.getMessage());

        }

    }

}

Предполагается, что тест выше упадёт. Давайте теперь заглянем в проблему чуть глубже.

Вообще, конечно, может случиться и так, что тест из примера пройдет успешно. Это произойдет в том случае, если ваша среда корректно настроена и хранилище доверенных сертификатов, используемое по умолчанию содержит сертификаты агентства, выпускающего сертификаты LetsEncrypt. C другой стороны, если бы у вас не было бы проблем, вы бы вряд ли искали решение, правда?

Чаще всего рассматриваемая проблема возникает, когда вы имеете дело с сертификатами, выпущенными локальными корпоративными сертификационными центрами.

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

Что вообще означает фраза «PKIX path building failed»?

Когда ваш код пытается обратиться к https-эндпоинту, удаленный сервер посылает вашему клиенту свой публичный ключ и сертификат, подтверждающий его (сервера) «личность». Клиенту, в свою очередь, необходимо решить может ли он доверять такому сертификату. Каждый сертификат подписан цифровой подписью издателя (третьей стороной), что означает, что проверить такую подпись возможно только с помощью публичного ключа издателя.

Но можем ли мы доверять издателю этого сертификата (третьей стороне процесса)? Публичный ключ издателя также сопровождается своим сертификатом, который может быть проверен идентичным путем. Такая цепочка имеет название certificate chain.

В чем состоит основная идея, лежащая в основе протокола https? Этот протокол использует т.н. криптографию открытого ключа (так же известную как «асимметричная» криптография) для того чтобы согласовать с сервером «симметричный» ключ (а фактически — пароль, при помощи которого будут кодироваться и декодироваться сообщения). Таким образом, на первом этапе взаимодействия, клиенту требуется публичный ключ сервера, чтобы при помощи него зашифровать сообщения фазы упомянутого согласования.

Для того чтобы клиент мог быть уверенным в том, что он действительно общается с сервером, с которым он думает, что общается, публичный ключ обычно сопровождается сертификатом. Сертификат — это такой документ, который содержит имя субъекта, а также публичный ключ, ассоциированный с именем субъекта. На основании всей информация сертификата, вычисляется хэш-строка, которая затем подписывается (шифруется) при помощи секретного ключа сертификационного агентства (CA), выдавшего данный сертификат. Единственным способом проверить валидность такого сертификата является вычисление хэш-строки сертификата и сравнение результата с расшифрованным «подписанным» хэшем. Успешно расшифровать подписанный хэш можно только при помощи публичного ключа агенства, который в свою очередь, также сопровождается своим сертификатом.

Любая реализация протоколов HTTPs/SSL подразумевает наличие некоего хранилища сертификатов, которые считаются «доверенными» (в англоязычной среде такое хранилище называется trust store). Таким сертификатам мы доверяем по умолчанию. Вообще говоря, таких хранилищ может быть несколько, и каждое может быть использовано для своих целей. Основное правило, которое необходимо соблюсти для успешной коммуникации вашего кода и HTTPs-сервиса — это наличие хотя бы одного сертификата из цепочки в доверенном хранилище. В Java (в том случае если вы не меняли дефолтное состояние вещей), доверенное хранилище находится в файле %JRE_HOME%/lib/security/cacerts. Для большинства Java дистрибутивов, такой trust store уже содержит сертификаты/ключи всех общеизвестных сертификационных агентств, так что у вас не должно будет возникнуть проблем при соединении с большинством публичных сервисов в Интернете. Однако, для интранет-сервисов дела обстоят не так безоблачно.

Сообщение «PKIX path building failed» означает, что ssl-библиотека Java в процессе валидации цепочки сертификатов, пришедшей с сервера не смогла обнаружить такой сертификат, который бы находился в используемом trust store.

Подготавливаем траст стор для того чтобы наш код доверял бы сертификату от тестового сервера

Мы собираемся применить комплексный подход к решению нашей задачи. Сперва нам необходимо подготовить доверенное хранилище, которое бы содержало сертификат, возвращаемый нашим тестовым сервером. Ниже перечислены шаги, которые необходимо выполнить:

  1. Получить файл сертификата, содержащий сертификат вашего сервиса. Это может быть сделано одним из двух способов. 1) спросить ваших разработчиков или девопсов, ответственных за имплементацию и деплоймент сервиса. 2) Открыть https ендпоинт в вашем веб-браузере, кликнуть на иконку «замочек» рядом с адресной строкой, следовать указаниям открывшегося диалога, который в итоге приведет вас к ссылке на экспортирование сертификата в виде файла. Нам подойдут сертификаты в форматах .pem или .cer.

  2. Создать какой-нибудь каталог, куда положить полученный файл. Открыть командную строку и перейти в созданный каталог. Важно убедиться в том, что ваша переменная окружения PATH содержит каталог %JRE_HOME%/bin (это необходимо для того, чтобы иметь возможность запускать утилиту keytool из любого места вашей файловой системы).

  3. Находясь в созданном каталоге, импортируйте файл сертификата в хранилище (которое пока еще не создано) используя следующую команду.

keytool -importcert -file your-cert-file.pem -keystore mytruststore -storetype PKCS12

Установите какой-нибудь пароль. Этот пароль будет использоваться при обращении вашего кода к созданному хранилищу. Также ответьте «Yes» на вопрос действительно ли вы хотите доверять импортируемому сертификату.

После того как импорт завершится вы должны будете увидеть новый файл mytruststore в каталоге с сертификатом. Этот файл — и есть ваше новое доверенное хранилище сертификатов, которое теперь содержит сертификат, возвращаемый вашим тестовым сервисом.

Как использовать новый trust store в моем Java-тесте?

После того, как мы создали новый траст стор, нам необходимо как-то сообщить нашему тестовому коду, что теперь ему следует работать с новым хранилищем. Это можно сделать либо установив значения для соответствующих системных свойств через параметры командной строки при вызове ваших тестов из консоли (это, например, удобно делать при интеграции ваших тестов с инструментами Continuous Integration) или установить эти значения прямо в исполняемом коде. Мы будем использовать второй способ. Свойства, значения для которых нам надо будет установить, такие: javax.net.ssl.trustStore and javax.net.ssl.trustStorePassword.

Предположим, что мы создали хранилище доверенных сертификатов в файле mytruststore, который находится в каталоге /home/me/ssl и пароль, установленный для нашего хранилища — mystorepass. Тогда неработающий пример из начала статьи можно было бы переписать таким образом:

package click.webelement.https;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

public class ApiWithSSL {

    static {

        System.setProperty("javax.net.ssl.trustStore", "/home/me/ssl/mytruststore");
        System.setProperty("javax.net.ssl.trustStorePassword", "mystorepass");

    }

    public static void main(String[] args) {

        try {
            HttpURLConnection connection = (HttpURLConnection) new URL("https://webelement.click").openConnection();
            int responseCode = connection.getResponseCode();
            if(responseCode != 200){
                System.out.println("Test failed with actual status code: " + responseCode);
            }else{
                System.out.println("Test passed");
            }
        } catch (IOException e) {
            System.out.println("Test failed with exception: " + e.getMessage());
        }

    }

}

Где мы просто добавляем блок статической инициализации в котором устанавливаем необходимые значения для наших свойств.

Такая настройка не обязательно должна находится в блоке статической инициализации. Она может быть добавлена в любое место, исполняемое до вызова https ендпоинта.

В моей следующей статье, вы узнаете как сделать доверенное хранилище сертификатов частью тестового проекта, таким образом, что оно будет распространяться вместе с тестовым кодом и использоваться в неизменном виде где бы ваши тесты не запускались. Такой подход потребует некоего стандарта подхода к формированию структуры тестовго проекта. В частности, использование таких фреймворков как Maven и JUnit.

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

How do I resolve PKIX “path building failed” errors for my agent when connecting to my Controller over SSL?

When establishing a secure SSL-based connection between your agent and Controller, the agent connectivity may fail with a PKIX error — even if you followed the Enable SSL for the Java Agent documentation instructions. This may be due to configuration in your environment or in the agent.

In this article…

  • What PKIX error may arise if the agent-to-Controller connectivity fails? 
  • What does the PKIX path building error mean?
  • What causes this error?
  • What is the most convenient resolution?
  • How do I import the correct certificates manually?
  • How do I troubleshoot further if I continue to see PKIX errors?
  • Resource Summary

What PKIX error may occur if the agent-to-Controller connectivity fails?

Even if you followed the instructions in the Enable SSL for the Java Agent documentation, given your environment OR agent configuration, the agent connectivity to your Controller over SSL may fail with the following PKIK error:

[system-thread-0] 02 Jun 2021 07:07:47,848  WARN SystemAgent - Certificate chain validation failed sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target attempting validation.
[system-thread-0] 02 Jun 2021 07:07:47,850 ERROR ControllerTimeSkewHandler - Fatal transport error while connecting to URL [/controller/instance/1265056/current-time]: 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
[system-thread-0] 02 Jun 2021 07:07:47,850 ERROR ControllerTimeSkewHandler - Error response from controller: Fatal transport error while connecting to URL [/controller/instance/1265056/current-time]

What does the PKIX path building error mean?

PKIX stands for Public Key Infrastructure X509Whenever Java attempts to connect to another application over SSL, the connection will only succeed if it can trust the application. 

In Java, trust is handled with a keystore, also known as the truststore (typically <agent_home>/<version_number>/conf/cacerts.jks or <agent_home>/conf/cacerts.jks in the AppDynamics Agent context). This contains a list of all known certificate authority (CA) certificates, and Java will only trust certificates that are signed by one of the CAs or public certificates that exist within that keystore. 

See Explaining the Chain of Trust — Learn What is it & How it Works and PKIX path building failed error message – CloudBees Support to learn more.

What causes this PKIX error? 

The PKIX  ‘path building failed’ error can arise due to:

  • If the agent is not able to locate the truststore (cacerts.jks), it won’t be able to validate the certificate produced by the Controller. Eventually, the PKIX ‘path building failed’ error will result.
  • Some enterprises may have an SSL interpreting proxy sitting between the agents and the Controller. In such situations, the root CA’s (which issued the certificate to your proxy) SSL certificate needs to be imported into the agent’s truststore.
  • In order to ensure a valid trust chain between the agent and the Controller, the intermediate certificate may also need to be imported, or the ‘PKIX path building’ will not be complete.
  • It is possible that you would want to only use your application truststore. In that case, the relevant certificates need to be imported into your application truststore.

What is the most convenient resolution to the PKIX error?

The most convenient solution is to replace the Agent’s current truststore (cacerts.jks) with a working agent’s truststore (i.e., an agent sitting in the same environment as the non-working agent node in question, but that is communicating fine with the Controller). 

To accomplish this:

  1. Take a backup of the cacerts.jks in the non-working agent node
  2. Copy over the cacerts.jks from an agent that is working fine and move it to the cacerts.jks in the non-working agent node’s directory, below :
    <agent_home>/<version_number>/conf/cacerts.jks

    or

    <agent_home>/conf/cacerts.jks
  3. Restart the agent and wait for 1-2 minutes. Verify whether the agent begins to report to the Controller.

If importing the truststore from an agent that is working is not an option, then follow the steps below, under Troubleshooting by manually importing the certificates.

Troubleshooting by manually importing the certificates

The following steps are a comprehensive approach to the problem.

  1. Review the output of the command below:

    <jre-home>/bin/keytool -printcert -sslserver <controller-host>:<controller-port> > cert.out


    This command will print the content of the certificate being presented by the endpoint that your agent speaks to (given your environment).

    For example, it could be directly talking to the SaaS Controller without an SSL interpreting proxy server OR there could be an SSL interpreting proxy server being managed by your organization intercepting all outgoing communication from all agents to the Controller. As a result, you may see two or more certificates in the certificate chain and metadata for those certificates which get captured in cert.out in the above command.

  2. Review the certificate chain:
    <jre-home>/bin/keytool -printcert -sslserver <controller-host>:<controller-port> -rfc > cert_rfc.out


    The above command helps us to print the raw certificate chain. Once we get this chain, it can be examined in a third-party tool called KeyStore Explorer. This helps you to visualize the certificate chain right from the top of the trust chain (i.e., the CA) down to the Controller.

  3. You can directly import this cert_rfc.out file to third party tool KeyStore Explorer and export the root and the intermediate entities’ certificates one by one by following the steps as seen under the heading Export a trusted certificate.

    Alternatively, you may follow the steps below on the KeyStore Explorer:
    1. Select the top certificate by clicking on the top root certificate under the ‘Certificate Hierarchy’.
    2. Click on Export in the bottom-most row of the KeyStore Explorer window.
    3. As soon as you click on Export in the above step, you’ll see another window that reads as Export Certificate from entry <your-certificate-name-selected-in-step1>. With Export Format as X.509 and PEM options selected, click on Export.
    4. Similarly, extract the root and the other intermediate certificates.
    5. Import the certificates into the agent’s truststore by executing the below commands:
      keytool -import -file root_ca.pem -alias root_ca -keystore cacerts.jks -storepass changeit
      keytool -import -file intermediate1.pem -alias intermediate1 -keystore cacerts.jks -storepass changeit
      keytool -import -file intermediate2.pem -alias intermediate2 -keystore cacerts.jks -storepass changeit

      In the above code snippet, most of the time it will be enough to just import the root certificate. In rare cases, you might want to import the intermediate certificates as well.


      If you wish to export the certificate from the browser, then please refer to
      Exporting SSL certificate from your browser.

  1. Restart the agent and after 1-2 minutes verify directly on the Controller whether the agent begins to report on the controller.

How do I troubleshoot further if I continue to see agent-related PKIX errors?

If you continue to see the PKIX errors in the agent log even after importing the correct certificates, please contact AppDynamics Support.

Resource Summary

  • Enable SSL for the Java Agent
  • Explaining the Chain of Trust — Learn What is it & How it Works
  • PKIX path building failed error message – CloudBees Support
  • Download Keystore Explorer
  • Export a Trusted Certificate
  • Exporting SSL certificate from your browser
  • My extension is getting a ‘PKIX path building failed’ error. Why? 

Let’s see how you can fix your “PKIX path building failed” error. This error occurs when you try to connect via HTTPS between two applications via a self-signed certificate.

The error will look something like this:

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

In case you did not know. The acronym PKIX stands for Public Infrastructure X509.

Issue description

A Successful connection between two SSL-based connections is only possible if the certificates are valid and trusted. Luckily, there is nothing to worry about if you are facing the issue. It is a well-known error message reported by the Java Virtual Machine. This error message is displayed when the Java environment does not have the information about the HTTPS server to verify that it is a trusted website.

The following are the common causes:

  • The most common reason for this error is the certificate provided by an internal Root CA or is a self-signed certificate. Therefore, it can confuse the Java Virtual Machine as it is not on the Java “Trusted” list.
  • A system firewall can also cause the issue. The firewall restricts the application’s connection to external systems that are unsecured. A valid certificate is required to access external systems.

Solution

You need to download and install the required certificates to fix your “PKIX path building failed” error.

Step 1 – Download the certificate

You can download the certificate using the following steps:

  1. Look for a URL in the error message and paste it to a browser.
  2. Now check if the URL you are visiting is secure. You can do this by looking for a lock icon on the left of the URL.
  3. Once you select the certificate, save the certificate to a file. You can choose DER encoded binary as the file format for the certificate.

At this point, you have not downloaded the certificate. The next step is to install the certificates in your system’s cacerts trust store. The cacerts is a trust store is used to authenticate peers.

Step 2 – Install the certificate.

You will need to use the keytool command to install your certificate.

See the command below:

keytool -importcert -trustcacerts -alias <alias name of the certificate> -file <path were we have saved the certificate> -Keystore “<path for the cacerts file>” -storepass changeit

The details will be according to your computer. In our case, the command will be:

keytool -importcert -trustcacerts -alias repo -file C:temprepo.cer -Keystore “C:Program FilesJavajdk1.8.0_131jrelibsecuritycarcets” -storepass changeit

Note:

  1. We are using jdk1.8.0_131; as a result, the cacerts file path for our system is “C:Program FilesJavajdk1.8.0_131jrelibsecuritycarcets”. This path can be different for you, depending on your system and the JDK version.
  2. We have named our certificate repo, and the path where we save our certificate is C:temprepo.cer.

Wrapping up

After this detailed guide, we hope you have a clearer picture and better understanding of why this PKIX path-building error occurs and what steps to take to solve it. 

YouTube player

You may also be interested in


About the Authors

Anto’s editorial team loves the cloud as much as you! Each member of Anto’s editorial team is a Cloud expert in their own right. Anto Online takes great pride in helping fellow Cloud enthusiasts. Let us know if you have an excellent idea for the next topic! Contact Anto Online if you want to contribute.

Support the Cause

Support Anto Online and buy us a coffee. Anything is possible with coffee and code.

Buy me a coffee


Table of Contents

  • How to fix PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException
    • Introduction
    • Cause of error
    • How to fix the above error

Introduction

In the last article, we were trying to enable communication over https between 2 applications using the self-signed certificate. Once the certificate was added and when we ran the application some users would have got the below error.

org.springframework.web.client.ResourceAccessException:

I/O error on GET request for «https://localhost:8100/customer/»: sun.security.validator.ValidatorException:

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:

unable to find valid certification path to requested target;

nested exception is 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

In this article, we will focus on how to fix the above error.

Cause of error

The reason, we get above error is that JDK is bundled with a lot of trusted Certificate Authority(CA) certificates into a file called ‘cacerts’ but this file has no clue of our self-signed certificate. In other words, the cacerts file doesn’t have our self-signed certificate imported and thus doesn’t treat it as a trusted entity and hence it gives the above error.

How to fix the above error

To fix the above error, all we need is to import the self-signed certificate into the cacerts file.

  • First, locate the cacerts file. We will need to find out the JDK location. If you are running your application through one of the IDE’s like Eclipse or IntelliJ Idea go to project settings and figure out what is the JDK location.
    For e.g on a Mac OS typical location of cacerts file would be at this location /Library/Java/JavaVirtualMachines/ {{JDK_version}}/Contents/Home/jre/lib/security
    on a Window’s machine it would be under {{Installation_directory}}/{{JDK_version}}/jre/lib/security
  • Once you have located the cacerts file, now we need to import our self-signed certificate to this cacerts file. Check the last article, if you don’t know how to generate the self-signed certificate correctly.
  • If you don’t have a certificate file(.crt) and just have a .jks file you can generate a .crt file by using below command. In case you already have a .crt/.pem file then you can ignore below command

##To generate certificate from keystore(.jks file) ####

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

Above step will generate a file called selfsigned.crt

  • Import the certificate to cacerts

#### Now add the certificate to JRE/lib/security/cacerts (trustore) #####

keytool importcert file selfsigned.crt alias selfsigned keystore {{cacerts path}}

for e.g

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

That’s all, restart your application and it should work fine. If it still doesn’t work and get an SSL handshake exception. It probably means you are using different domain then registered in the certificate.

This site uses cookies from Google to deliver its services, to personalise ads and to analyse traffic. Information about your use of this site is shared with Google. By using this site, you agree to its use of cookies.

Author: Abhishek Bathwal

While developing some application, we might sometimes come across below error which the maven throws while building the application:

Reason: The error due to the system firewall. The system firewall restricts the application to connect to external unsecured systems. The firewall requires a valid certificate to allow access to the external systems.

Solution: The solution is very simple. We just need to install the required certificates of the external system in our system so the firewall allows us to interact with the external system and complete our process.

We are going to perform two activities:

  1. Download the Certificate.
  2. Install the Certificate.

To download the certificate, follow the below steps:

  1. Take the particular URL from the error and copy it to a browser (In the above error the url is https://repository.mulesoft.org/releases/).

  1. Now to the left of the URL there is a lock icon (). Click on this icon and a window will pop up. From the window, select the certificate.

  1. Once we select the certificate, it will redirect to another window. From there we have to select the Details tab and from the Details click on Copy to File. After clicking again, a new window will pop up. In that window, select next.

  1. After we perform all the above steps, we will be redirected to a new window where we need to select the format for the certificate. We will have to choose DER encoded binary and click on Next.

  1. Now we need to choose a location where we need to save the certificate and we also need to give some name to the certificate.

  1. Once a File name is given and saved, then select Next. It will direct us to another window showing the details. If all the details are correct, click on Finish. A export Success pop up will appear.

Note: I saved the File name as repo.

So, the downloading of certificates is done. Now the next process is to install the certificate in the cacerts file of the jdk installed in our system using the command line.

Installation of the Certificate from Command line:

Command for installation: keytool -importcert -trustcacerts -alias <alias name for the certificate> -file <path were we have save the certificate> -keystore “<path for the cacerts file>” -storepass changeit

For me the Command will be: keytool -importcert -trustcacerts -alias repo -file C:UsersDELLDesktoprepo.cer -keystore “C:Program FilesJavajdk1.8.0_131jrelibsecuritycarcets” -storepass changeit

Note

  1. I am using jdk1.8.0_131 so the cacerts file path for my system is “C:Program FilesJavajdk1.8.0_131jrelibsecuritycarcets”. It may differ for you based on your system and jdk version.
  2. I have given the alias name as repo and the path where I save my certificate is C:UsersDELLDesktoprepo.cer
To install the certificate, follow the below steps:
  1. Open Command Prompt as an Administrator and use the command for installation and press enter.

  1. Once the command is executed, it will ask for confirmation. Write Yes and the certificate will be installed with confirmation.

In the above process, we have downloaded and installed the certificate successfully in our system.

Now if we will execute the application it will not show certificate issues and will also download the required data from that particular system.

Thank you!

Понравилась статья? Поделить с друзьями:
  • Error pathspec first commit did not match any file s known to git
  • Error patch failed
  • Error pasting and does not give a valid preprocessing token
  • Error passphrase chosen is below the length requirements of the usm min 8
  • Error passing const as this argument discards qualifiers