Load ONLY the JKS in Java to call URL - java

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

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.

Client Authentication Tomcat - trustAnchors parameter must be non-empty

I know this question appears no stackoverflow a lot, and the exception is to do with a missing truststore - but here is my issue:
Using Apache Tomcat v7.0.56 as server on Windows with Java 8.0.71
modified tomcat/conf/server.xml to include SSL Connector with truststoreType="PKCS12", truststoreFile="conf/regtomcat.truststore" truststorePass="password"
I launch tomcat and I know it is reading this truststore file correctly as I originally did not have the file in pkcs12 format and tomcat reported an error on startup. I also have tried breaking the file location just to see tomcat startup fail as it can not find the file. So tomcat launches okay - it is reading the truststore which must mean it exists and can be read.
I load a p12 file into my browser certificate, and go to my application URL. I then get the tomcat error:
handling exception: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException:
the trustAnchors parameter must be non-empty
Given that my trustore exists, and contains my certificate - what could the problem be?
I generated all certificates and truststores using keytool. The truststore was created using the command
keytool -importcert -alias regClient -storetype PKCS12 -keystore regtomcat.truststore -file regClient.cer
One probable reason might be that if we use same .jks file as a keystore and as a truststore, then the server start up is failing with following error : java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty.
Keystore is to store the ServerCerts and TrustStore is to store the CA certs. On adding at least one CA certificate in the .jks, above issue will be resolved.
Okay - the problem was the certificate was created using JDK 1.8 and the tomcat was running with JRE 1.7 - for whatever reason this caused an issue, so the fix was to use JRE 1.8 and now everything works okay.
Faced same issue. My keystore only had private key pair of the website. Imported the public certificates from the key pair all the way down to the root and it worked.
Faced same issue. The cause was far more basic: the .jks file must be readable for the account under which tomcat service runs. Though we have it as a systemctl service (hence started/stopped from root) the account was tomcat, so a simple chown tomcat:tomcat for the .jks store did the job!
For me the issue was I was passing null to the keyword as password wherein the password was changeit
ks.load(fis, "changeit".toCharArray());

WsImport unable to find imported certificate

Apologies for yet another "unable to find certificate" question.
I'm developing on a Windows 7 machine. I am using multiple Java versions and because of that am explicit about paths to the used java version (here Java6). I achieve this by the following two lines:
set path=c:\Program Files\Java\jdk1.6.0_45\bin;%path%
set java_home=c:\Program Files\Java\jdk1.6.0_45
I need to use a 3rd party web service https://service.gov/Service.svc?wsdl that provides a certificate.PFX certificate (both service URI and certificate file are renamed as a way to protect the 3rd party's interests). I have made sure that after importing the certificate file in Windows I can open the WSDL file in my browser.
I first import the certificate in my keystore (using Administrator Command Prompt to get access to write in the system folder):
keytool -importkeystore -srckeystore certificate.pfx -srcstoretype pkcs12 -keystore "c:\Program Files\Java\jdk1.6.0_45\jre\lib\security\cacerts"
I get a success notification. Still, I make sure that the new certificate is present in the output of:
keytool -list -keystore "c:\Program Files\Java\jdk1.6.0_45\jre\lib\security\cacerts"
Then I create a new folder containing blank subfolders called src and classes. Once this is done, I run wsimport from that new folder (using Java class instead of binary to make sure I am explicit about the truststore being used):
java -classpath "c:\Program Files\Java\jdk1.6.0_45\lib\tools.jar" -Djavax.net.ssl.trustStore="c:\Program Files\Java\jdk1.6.0_45\jre\lib\security\cacerts" -Djavax.net.ssl.trustStorePassword=changeit com.sun.tools.internal.ws.WsImport https://service.gov/Service.svc?wsdl -s src -d classes
The output is the following:
parsing WSDL...
[ERROR] sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Failed to read the WSDL document: https://service.gov/Service.svc?wsdl, because 1) could not find the document; /2) the document could not be read; 3) the root element of the document is not <wsdl:definitions>.
[ERROR] failed.noservice=Could not find wsdl:service in the provided WSDL(s):
At least one WSDL with at least one service definition needs to be provided.
Failed to parse the WSDL.
The WSDL file contains and is used by other organisations, so the problem is pretty certainly not on the 3rd party's side.
Am I missing something? To me it all seems obvious by now, but it still doesn't work. I have also tried this with Java8, and the result is pretty much the same. The only difference is that in Java8, the WsImport class no longer exists, so I am using the wsimport.exe binary.
Thanks in advance for any ideas or hints.
The pfx file (which contains a certificate and also a private key) is for client authentication, while a truststore is for validating the server certificate. It is important to understand the difference between a keystore and a truststore.
You have imported the client certificate (and key) into the default truststore (cacerts). What you should have done instead is:
Import the issuer (CA) of the SSL certificate of the server into cacerts. You can skip this step if the CA certificate is already in cacerts, which is probably the case here.
Use the pfx file as your keystore for client authentication. The easiest way is to convert it to jks: https://stackoverflow.com/a/3054034/2672392 The properties to pass to wsimport are "javax.net.ssl.keyStore" and "javax.net.ssl.keyStorePassword".
See this answer for a list of important SSL properties: https://stackoverflow.com/a/5871352/2672392

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

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);

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

Categories