How to connect to SSL Certificate Webservice without installing to keystore? - java

I'm trying to connect to a SSL webservice that requires a PKCS12 certificate.
Question: is it possible to not installing the certificate to the local keystore, but load it dynamically during runtime?
I tried as follows:
static {
KeyStore.getInstance("PKCS12").load(this.getClass().getClassLoader()
.getResourceAsStream("myfile.p12"), "password".toCharArray());
}
But the result:
sun.security.validator.ValidatorException: PKIX path building failed.
sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target.
So obviously it does not work. But why?
Sidenote: the linked SO question does not answer my question, as it targets trustStore, but my question is about keystore.

The problem has nothing to do with this code. Your truststore doesn't trust the server's certificate. If it's self-signed, you'll have to import it. Better still, get it signed by a CA.

The problem is that although your keystore has been created and loaded with your client certificate (assuming that everything is good with it), the SSLContext is not configured to use it.
Try:
Keystore keystore = KeyStore.getInstance("PKCS12").load(this.getClass().getClassLoader()
.getResourceAsStream("myfile.p12"), "password".toCharArray());
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore,"password".toCharArray()).build();
SSLContext.setDefault(sslcontext);

Related

SunCertPathBuilderException; JAVA_OPTS with keystore required?

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.

Load ONLY the JKS in Java to call URL

I have a JKS with this information:
Importing this JKS in SOAP UI, I can call the remotes URLs without problem.
OK, but I want to do the same in Java (only with the JKS), with this instruction:
System.setProperty("javax.net.ssl.keyStore","C:\\myJKS.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "myPassword");
The error is:
the trustAnchors parameter must be non-empty
My idea is work like SOAP UI, only load or import the JKS and no more.
PD: I've imported in the JKS the cert:
And the error was:
unable to find valid certification path to requested target

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

org.apache.axis2.AxisFault: sun.security.validator.ValidatorException:

org.apache.axis2.AxisFault: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
I am getting the baove exception, i know it is because it is not able to find the certificates.
when i created a new JKS file with only the certificate enteries provided by the 3rd party and setting in system.setProperty("javax.net.XXXX") it works.
But due to this my other functionalities in application does not work as it is not able to find any certificate.
so i created jssecacerts using class file and imported the two certificates as well, but pointing and setting in system properties this jssecaerts file, it does not work and rest everything works fine.
What could be the issue..???
You could add your additional certificates for use by Axis2 in your own X509TrustManager and build an SSLContext from it. This is described in this answer.
Then you would have to pass the subsequent SSLSocketFactory to Axis2 using an Apache HttpClient 3.x SecureProtocolSocketFactory (see the Axis 2 documentation on the subject).

Categories