Copying java keystore - java

I have a valid keystore on my local development machine, which contains a certificate for accessing a webservice via HTTPS.
I access this keystore in my project via:
System.setProperty("javax.net.ssl.truststore", "C:\\<workspaceprojectPath>\\SIPkeystore\\truststore.jks"); // sollte wohl auch ohne Keystore klappen
System.setProperty("javax.net.ssl.keyStore", "C:\\<workspaceprojectPath>\\SIPkeystore\\SIPkeystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "SECRET");
Now I want to access that certificate from another project. There I provide the same (full) path to the keystore in the other (local) project directory.
Apparently the path is still found by the jvm and the property is being set, but on accessing the web service I get the same error message as if I hadn't added the keystore at all.
When trying run the application I get a
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid
certification path to requested target
Is there a possibility to copy an existing keystore? This will be important also, when we deploy the application to our server. The application will run as stand-alone jar. (no web server)
EDIT:
Ok, copying the keystore does not seem to be the problem, as I am able to run the original application while using a local copy of the original keystore files. It seems like it is a configuration issue.

Is there a possibility to copy an existing keystore?
Yes. From the file system perspective it is just a file.
I imagine that the problem is one of the following:
The relevant properties are not correctly set in the other project.
The other JVM cannot find the keystore file (e.g. because of chrooting or some such)
The other JVM doesn't have the required permissions to access/read the keystore file.
The read access is being blocked by (for instance) SELinux.

First of all, if Web service doesn't require client certificate (i.e. that you introduce yourself) there's no need for keystore - you only need truststore.
It could be that other project cannot access truststore, so just for exercise, try to open C:\<workspaceprojectPath>\SIPkeystore\truststore.jks there and read first few bytes. If you succeed, it means that the other project has some other truststore set as default, so in that case try:
System.out.println(System.getProperty("javax.net.ssl.trustStore"));
Also, bear in mind that Java is case-sensitive, and you specified javax.net.ssl.truststore property instead of javax.net.ssl.trustStore. Try fixing this also.

The valicert class 3 CA certificate is not in your default truststore (which is probably the cacerts file in your JRE lib/security directory, but see the JSSE documentation for the full story).
I think you should create your own truststore file (which can be a copy of the cacerts file) and add the valicert root ca to this. Then point to this file with the javax.net.ssl.trustStore system property.

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.

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.

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

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.

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