Expand my Community achievements bar.

SOLVED

SSL connection to remote server issue

Avatar

Level 7

Hi All,

 

We have a component working for 8 years, all of a sudden it stops working. 

 

The code is

 

import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
....
String remoteUrl = "https://myremotesite.com";
HttpClient client = new HttpClient(clientParams);
HttpMethod method = new GetMethod(remoteUrl);

 

It throws a javax.net.ssl.SSLHandshakeException as:

 

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

 

 

But I can see my SSL certificate under the ssl-service and the URL bar from my publish server.

Screenshot 2024-01-12 at 3.18.28 PM.png

 

Screenshot 2024-01-12 at 3.19.06 PM.png

 

 

Also, I tested the code via Unit Test and it works even if I don't have an SSL certificate on my Mac.

 

I look up this error, it says the certificate can't be picked up by the JDK. Any idea of that how to solve it?

 

Thanks!

 

-kt

 

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

@kevingtan ,

As @pulkitvashisth pointed out this issue typically occurs when the JVM can’t validate the SSL certificate from the server.

I followed the below steps to fix this issue on our on-premise AEM Servers where you can SSH into these AEM servers.

Assuming you are trying to connect to "https://myremotesite.com" from AEM servers:
Run the below command to download the root and intermediate chain certificates.
ssh into AEM server and change directory to /tmp or any other folder where you have write access and run the below command script.

 

$ openssl s_client -showcerts -verify 5 -connect myremotesite.com:443 < /dev/null | awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{ if(/BEGIN CERTIFICATE/){a++}; out="cert"a".pem"; print >out}'
  for cert in *.pem; do 
        newname=$(openssl x509 -noout -subject -in $cert | sed -nE 's/.*CN ?= ?(.*)/\1/; s/[ ,.*]/_/g; s/__/_/g; s/_-_/-/; s/^_//g;p' | tr '[:upper:]' '[:lower:]').pem
        echo "${newname}"; mv "${cert}" "${newname}" 
  done

 

Next, convert the downloaded certificates from .pem to .der format using the below commands.

 

$ openssl x509 -outform der -in my_remotesite_ca.pem -out my_remotesite_ca.der

 

Do the same for other certificates created in this folder.
 
Lastly, run below keytool commands one-by-one to add entire certificate chain to the java truststore

 

$ keytool -importcert -trustcacerts -file my_remotesite_ca.der -alias my_remotesite_root -keystore <javaInstallationPath>/jre/lib/security/cacerts -storepass changeit

 

 

Hope this helps!

View solution in original post

7 Replies

Avatar

Community Advisor

The error you’re encountering, " 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 ", typically occurs when the JVM can’t validate the SSL certificate from the server.

Related reference:

https://stackoverflow.com/questions/21076179/pkix-path-building-failed-and-unable-to-find-valid-cert...

Here are a few potential solutions:

  1. Check the Certificate Store: The problem might have started after updating your JDK. You were probably using the standard Java truststore called ‘cacerts’. You can find this in JDK_HOME/jre/lib/security/cacerts. Copy this file from your old to your new JDK and test if the issue is resolved.
    https://stackoverflow.com/questions/60540641/geting-pkix-path-building-failed-sun-security-provider-...

  2. Install the Required Certificates: Install the required certificates of the external system in your system so the firewall allows you to interact with the external system
    https://apisero.com/how-to-resolve-pkix-path-building-failed-unable-to-find-valid-certification-path...

  3. TrustServerCertificate: 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.
    https://techcommunity.microsoft.com/t5/azure-database-support-blog/pkix-path-building-failed-unable-...

  4. Use InstallCert: You can use the Java program InstallCert to add the server’s certificate to your Java keystore. However, this approach is more suitable for a development environment and might not be ideal for a production environment .
    https://stackoverflow.com/questions/21076179/pkix-path-building-failed-and-unable-to-find-valid-cert...

If none of these solutions work, it might be best to reach out to your system administrator or support team for further assistance.

Avatar

Level 7

Hi @pulkitvashisth ,

 

Thanks for the suggestion. I actually did that before making a post here. Normally the certificate is imported if it's seen on the URL bar, especially I can see it via the publish ssl certificate store. My understanding is that I may make an incorrect format for the trusted store. What puzzles me why it was working and not anymore without changing the JDK. I actually found another temporary solution for it.

Avatar

Administrator

@kevingtan Did you find the suggestions from users helpful? Please let us know if more information is required. Otherwise, please mark the answer as correct for posterity. If you have found out solution yourself, please share it with the community.



Kautuk Sahni

Avatar

Level 7

The issue is that the JDK somehow can't load the ssl certificate, can be certificate location or format issue. The trusted stored is loaded as:

-Djavax.net.ssl.trustStore=/apps/aem65/mysite/ssl/trusted.keystore

I tried consolidate the system jdk cacerts and the customized trusted.keystore, but it doesn't work, either.

My connection is not necessary secure, so I set the SSL connection context to accept all kind of the certificates. I found a useful package here:

 

So before making a connection, trigger the ignore ssl certificate method, for example in my code:

 

String remoteUrl = "https://myremotesite.com";
(new UnsafeSSLHelper()).ignoreSSLCertif();
HttpClient client = new HttpClient(clientParams);
HttpMethod method = new GetMethod(remoteUrl);

 

It will open up the connection successfully.

 

Thanks for your help!

 

-kt

 

Avatar

Correct answer by
Community Advisor

@kevingtan ,

As @pulkitvashisth pointed out this issue typically occurs when the JVM can’t validate the SSL certificate from the server.

I followed the below steps to fix this issue on our on-premise AEM Servers where you can SSH into these AEM servers.

Assuming you are trying to connect to "https://myremotesite.com" from AEM servers:
Run the below command to download the root and intermediate chain certificates.
ssh into AEM server and change directory to /tmp or any other folder where you have write access and run the below command script.

 

$ openssl s_client -showcerts -verify 5 -connect myremotesite.com:443 < /dev/null | awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{ if(/BEGIN CERTIFICATE/){a++}; out="cert"a".pem"; print >out}'
  for cert in *.pem; do 
        newname=$(openssl x509 -noout -subject -in $cert | sed -nE 's/.*CN ?= ?(.*)/\1/; s/[ ,.*]/_/g; s/__/_/g; s/_-_/-/; s/^_//g;p' | tr '[:upper:]' '[:lower:]').pem
        echo "${newname}"; mv "${cert}" "${newname}" 
  done

 

Next, convert the downloaded certificates from .pem to .der format using the below commands.

 

$ openssl x509 -outform der -in my_remotesite_ca.pem -out my_remotesite_ca.der

 

Do the same for other certificates created in this folder.
 
Lastly, run below keytool commands one-by-one to add entire certificate chain to the java truststore

 

$ keytool -importcert -trustcacerts -file my_remotesite_ca.der -alias my_remotesite_root -keystore <javaInstallationPath>/jre/lib/security/cacerts -storepass changeit

 

 

Hope this helps!

Avatar

Level 7

@Sudheer_Sundalam ,

 

This is very helpful because eventually I will have to validate the certificate.

 

Thanks!

 

-kt

Avatar

Community Advisor

This happens when organization's VPN and certificate chain is updated. The browser automatically acquire the SSL certificates and validates using the updated certificate chain but sometimes we need to manually validate the certificate and add it to java truststore.

The best way to validate the certificate chain of given website in these cases is to run the curl command with verbose on from the AEM Server machine to see the entire SSL handshake.

curl -v https://mywebsite.com