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.
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
Solved! Go to Solution.
Views
Replies
Total Likes
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
$ openssl x509 -outform der -in my_remotesite_ca.pem -out my_remotesite_ca.der
$ keytool -importcert -trustcacerts -file my_remotesite_ca.der -alias my_remotesite_root -keystore <javaInstallationPath>/jre/lib/security/cacerts -storepass changeit
Hope this helps!
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:
Here are a few potential solutions:
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-...
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...
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-...
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.
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.
@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.
Views
Replies
Total Likes
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
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
$ openssl x509 -outform der -in my_remotesite_ca.pem -out my_remotesite_ca.der
$ keytool -importcert -trustcacerts -file my_remotesite_ca.der -alias my_remotesite_root -keystore <javaInstallationPath>/jre/lib/security/cacerts -storepass changeit
Hope this helps!
This is very helpful because eventually I will have to validate the certificate.
Thanks!
-kt
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