SunCertPathBuilderException; JAVA_OPTS with keystore required? - java

When connecting via a java API service to a remote server by https I got the following exception
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
The server is a Windows Server 2012 which has the corresponding wildcard certificate installed as root certificate too.
I've used keytool to import that exact same certificate to the keystore called cacerts, so the jvm is using it to prevent the exception above.
As keytool shows, the certificate is installed correctly but the handshake exception still occurs when connecting to the server.
I've checked the windows environment variables on the server and found out that the JAVA_OPTS is missing.
Even tried restarting the entire server but this did not help either.
In order to get it work, do I need to add the environment variable manually referencing the keystore as shown below?
-Djavax.net.ssl.trustStore=C:\path\to\cacerts

I was able to fix this issue by adding the certificate to the java applications keystore too.

Related

PKIX path building failed in Java application, for self-signed SSL certificate

I created a pair of SSL certificates using OpenSSL, self-signed, to secure the HTTPS connection for a JBoss application.
When I ran the application and tried to get access by HTTPS, it did not show the site and threw an error in my console:
PKIX path building failed in Java application
I know that I should import some certs into Java, like what they said:
The long story short here is to run java InstallCert server:1234 to
generate a file called jssecacerts. Then, drop this file in
${JAVA_HOME}/lib/security directory.
What I do not understand:
1.in fact I try to get access to host B from host A, using HTTPS, why should I add the certificate of my own host to Java, not the client one?
2.using this method, there is nothing to do with my actual certificates (I mean .key and .crt), is that normal?
you need to enter your certificate inside java cacert file
This link demonstrate it the best.
Step 1 : Download certificate
Step 2 : store inside cacert
That is it! your problem resolved.

Why java uses default location keystore/truststore of JAVA_HOME/lib/security/cacerts though I have supplied -Djavax.net.ssl.trustStore properties

In my java application I am running with supplied -Djavax.net.ssl.trustStore System properties as below.
-Djavax.net.ssl.trustStore=/myapp/app.jks -Djavax.net.ssl.trustStorePassword=XXXXX -Djavax.net.ssl.trustStoreType=jks -Djavax.net.debug=ssl
This is my Complete command line :
$JAVA_HOME/bin/java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp -Xms512m -Xmx1024m -XX:MaxPermSize=192m -Djavax.net.ssl.trustStore=/myapp/app.jks -Djavax.net.ssl.keyStore=/myapp/app.jks -Djavax.net.ssl.trustStorePassword=XXXXX -Djavax.net.ssl.keyStorePassword=XXXXX -Dweblogic.security.SSL.ignoreHostnameVerification=true -Djavax.net.debug=ssl -Djavax.net.ssl.trustStoreType=jks -cp /Oracle/Middleware/Oracle_Home/wlserver/server/lib/wlfullclient.jar:/myapp/stand‌​alone/lib/asm-5.0.3.jar:/myapp/standalone/lib/castor-1.3.2-core.jar:/myapp/standa‌​lone/lib/myAPP_final.jar
But java is not using that certificate from custom keyStore from the custom path. It is by default going to $JAVA_HOME/lib/security/cacerts with that I am getting below exception :
java.net.ConnectException: t3s://myapphost.com:7500: Destination 10.243.155.222, 7900 unreachable; nested exception is:
javax.net.ssl.SSLHandshakeException: General SSLEngine problem; No available router to destination
When i am importing and adding same certificate in the $JAVA_HOME/lib/security/cacerts it not giving any Exception.
I have refer and this post and try to configured same things in $JAVA_HOME/jre/lib/security/java.security and added following entry:
javax.net.ssl.trustStore=/myapp/app.jks
javax.net.ssl.trustStorePassword=XXXXX
javax.net.ssl.trustStoreType=jks
Still i am facing same problem.
My Question and problem here is, why java always goes java default keyStore location: $JAVA_HOME/lib/security/cacerts though i have supplied and configured my own custom keyStore using : -Djavax.net.ssl.trustStore=/myapp/app.jks -Djavax.net.ssl.trustStorePassword=XXXXX -Djavax.net.ssl.trustStoreType=jks -Djavax.net.debug=ssl
And if i am importing same certificate in default java keyStore loation it is working fine for me.
where and what all i need to change to configure different keystore to avoid to above exception.
After seeing this Post I have configured and supplied following system properties -D option it resolved the problem for me. Hope it will help to others so i am posting it.
-Dweblogic.security.CustomTrustKeyStoreFileName=/myapp/app.jks
-Dweblogic.security.TrustKeyStore=CustomTrust
-Dweblogic.security.CustomTrustKeyStorePassPhrase=XXXXXPWD
-Dweblogic.security.CustomTrustKeyStoreType=jks
I have understood following things which i have kept in Note: of -Dweblogic.security.TrustKeyStore parameter.
Note 1: -Dweblogic.security.TrustKeyStore will have following options and internal interpretation
-Dweblogic.security.TrustKeyStore=JavaStandardTrust (We should use when the trusted CAs in the JDK's cacerts, specify this)
-Dweblogic.security.TrustKeyStore=DemoTrust (We should use when the trusted CAs in DemoTrust.jks and in the JDK's cacerts, specify this)
-Dweblogic.security.TrustKeyStore=CustomTrust (We should use when the trusted CAs from another keystore, specify this).
Note 2:
Any time if you got below Exception, it means your java application is not finding certificate in the specified trust-store.
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:385)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
at sun.security.validator.Validator.validate(Validator.java:260)
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:unable to find valid certification path to requested target,It is telling the same.
Note 3:
Important things try to cogfigured -Djavax.net.debug=ssl for seeing more detail view of logs. Normally without that parameter we wont be able to see more details log.

Error when trying to connect through SSL. Unable to find valid certification path to requested target

I am totally new to web services. I am tying to connect through SSL connection. I followed this site: SSLHandshakeException: PKIX: unable to find valid certification path to requested target , this thread How to solve javax.net.ssl.SSLHandshakeException Error? and I did add the certificate to the keystore as follow:
keytool -importcert -alias <some name> -file <Certifacate path> -keystore "%JAVA_HOME%/jre/lib/security/cacerts" -storepass changeit
and I checked it is exists by using keytool -list command
The problem is that I got this error message when I trying to connect through SSL in the application:
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
I also tried to add the trustStore location and password in the application as follow:
System.setProperty("javax.net.ssl.trustStore","C:\\Program Files (x86)\\Java\\jre7\\lib\\security\\cacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
But still got the same error.
I am using Jdeveloper 11g R1 and JDK 7, if that's help.
Update:
After further reading some solutions said I need to make this path:
C:\Program Files\Java\jdk1.7.0_09\jre\lib\security\cacerts
As truststore
I replace the above java statement to be as follow:
System.setProperty("javax.net.ssl.trustStore","C:\\Program Files\\Java\\jdk1.7.0_09\\jre\\lib\\security\\cacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
but still I am getting the same error !!
After I got the certificate form third party I did the following:
Adding the certificate to the trusted root certificate in the browser with server Authentication check form the advance option.
Adding the certificate to the trust certificate using keytool options in the command prompt refer to this link: Resolving javax.net.ssl.SSLHandshakeException for mor information.
After long search I found that the cause of the problem unable to find valid certification path to requested target as follow: (Note: that's what I found out there may be more)
a. There is a missing intermediate certificates that is not added.
to solve this issue you need to add the root certificate and all the other will be added by default. To find out the certificate used by your third party refer to the following links. Basically, the proposed solution will provide you with a java class called (InsertCert.java) that will provide you with the certificates used by the server. what do you need is to pass the host name as a parameters. Find the details in the following links:
No more 'unable to find valid certification path to requested target'
Step by step video to solve the issue using information from the provisos link
b .You are adding the certificate in the wrong cacerts file.
To solve this issue refer to the same java class mentioned earlier (InsertCert.java) and it will provide with the correct cacerts path in my case I am using Jdeveloper 11.1.1.7 and the path is:
C:\Oracle\Middleware\JDeveloper\JDeveloper11117\jdk160_24\jre\lib\security\cacerts

Getting error: PKIX path building failed: unable to find valid certification path to requested target

I'm trying to send a xml to another system via web service. But while trying to send i'm getting the following error. I've installed the certificate they gave to me. but still its not working.
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
There are two possible sources for this error:
either the opposite side is using genuinely untrusted certificate (self-signed or signed by untrusted CA),
or the opposite side is not sending certificate validation chain (e.g. there is intermediate signing certificate along the way to your trusted CA, but this ceriticate is not present in the SSL handshake).
Solution for the first case is to add the untrusted CA (or the ceriticate itself) to your JRE truststore (${java.home}/lib/security/cacerts) or better - create your own truststore (which will not get removed when upgrading Java) and provide that to your application via javax.net.ssl.trustStore JVM property.
Solution for the second case is either to go with the first case solution or better - convince the opposite side to send correct certificate chain.
Add certificate to JRE truststore # ${java.home}/lib/security/cacerts OR if you have your own trustStore & provide path to that in your application/JVM. For example one possible way could be
or via java code
import java.util.Properties;
...
Properties systemProps = System.getProperties();
systemProps.put("javax.net.ssl.keyStorePassword","passwordForKeystore");
systemProps.put("javax.net.ssl.keyStore","pathToKeystore.ks");
systemProps.put("javax.net.ssl.trustStore", "pathToTruststore.ts");
systemProps.put("javax.net.ssl.trustStorePassword","passwordForTrustStore");
System.setProperties(systemProps);
...
For more refer to details on RedHat site
May be it will help refer to question

GlassFish connecting to SLL web service

I have a web app running on GlassFish v3 locally. The app connects to a REST web service that is on another server (not local). The connection is done through HTTPS. While trying to connect I get:
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
I added the cert from the external ws directory to the local java keystore but that did not fix the problem.
Do I have to instruct GlassF to use the local keystore or something ? Or just by adding it to the java keystore it should work for the local GlassF too ?
You have two options:
1.) Replace the cacerts in the $JAVA_HOME/jre/lib/security directory with your keystore.
2.) Change the keystore at runtime like this:
System.setProperty("javax.net.ssl.keyStore", <path to the new keystore>);
System.setProperty("javax.net.ssl.keyStorePassword",<password of the keystore>);
System.setProperty("javax.net.ssl.trustStore",<path to the new keystore>);
Hope that helps!
EDIT: You might find this question helpful as well. The selected answer suggests to:
1.) Copy your keystore file to C:\glassfish3\glassfish\domains\domain1\config\
2.) Configure GlassFish to use SSL

Categories