Use keystore file to run client for a SOAP WS - java

I was given a SOAP WS to work with.
They gave me the wsdl file from which I was able to create client stub (I've used wsdl2java utility within cxf).
With that wsdl I was also give a .keystore file and the thing is I do know know how to add it to my keytool (is this is even the right way of putting it?).
I've built a junit test that I run to test my client but I constantly get
HTTP transport error: 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
Where can I find an easy guide on what to do with this .keystore file?
Thanks

The error means that the server certificate could not be found in your truststore. Check the contents of the .keystore file to see whether it contains the server certificate (listed as trustedEntry in your truststore). If yes, set the following system properties (either using -D JVM parameter or System.setProperty()).
javax.net.ssl.trustStore=<<your .keystore>>
javax.net.ssl.trustStorePassword=<<keystore password>>
If these properties are not set, the default ones will be picked up from your the default location.[$JAVA_HOME/lib/security/jssecacerts, $JAVA_HOME/lib/security/cacerts]
To view the contents of keystore file, use
keytool -list -v -keystore file.keystore -storepass mypassword
To debug the ssl handshake process and view the certificates, set the VM parameter -Djavax.net.debug=all
If the web service requires 2 way SSL, the client needs to send its identity (picked up from your keystore). In this case, your .keystore will contain a privateKeyEntry which will be sent to the server during handshake process. To configure this, set the JVMM properties javax.net.ssl.keyStore and javax.net.ssl.keyStorePassword to point to your keystore.

The next works for me:
Application server configuration. Apache Tomcat/7.0.52. server.xml: set clientAuth="true" in the https connector.
Application server configuration. Apache Tomcat/7.0.52. tomcat-users.xml: crate a user with the DN of the user as it appears in your certificate (subject)
Web service JAX-WS web service eclipse tutorial. Thanks Arpit! Add it a security constraint in the deployment descriptor (web.xml)
Client. Generated with apache-cxf maven plugin.
Main class:
HelloWorldImplService helloWorldImplService = new HelloWorldImplService();
HelloWorld helloWorld = helloWorldImplService.getHelloWorldImplPort();
SayHelloWorld parameters = new SayHelloWorld();
parameters.setArg0("World");
SayHelloWorldResponse helloWorldResponse = helloWorld.sayHelloWorld(parameters);
System.out.println(helloWorldResponse.getReturn());
Client JVM options:
-Djavax.net.ssl.trustStore=/xxxx/cacerts.jks -Djavax.net.ssl.trustStorePassword=xxxx -Djavax.net.ssl.keyStore=/xxx/user.jks -Djavax.net.ssl.keyStorePassword=xxxx
You can take a look here: Java SOAP client with certificate authentication

An excellent blog to help you understand the keystores and certificates imports required for HTTPS SSL handshake:
http://ruchirawageesha.blogspot.in/2010/07/how-to-create-clientserver-keystores.html
Hope it helps you to setup ur client keystore correctly in order to call the web services.
Good Luck!

Related

Using https in Rest web service

I have a Rest web service developed in java, glassfish, running on a centos server.
We recently opted to use the https protocol and started testing through the test certificate provided by glassfish itself at deployment time (port 8181).
Using Postman for testing I just needed to disable one option in the configuration: "SSL certificate verification".
However the modules that consumed my service, service destop, in java, started to throw exceptions.
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
In test environment, windows, the lines below corrected the problem, already in production, hundreds, could not solve.
String certificatesTrustStorePath = "/etc/alternatives/jre_1.8.0/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore", certificatesTrustStorePath); System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
The error in centos is the one presented in the post below, already read about the various reasons but could not solve.
Error - trustAnchors parameter must be non-empty
If you know how to solve in linux I appreciate it,but the question is not this ...
Do these lines I have published specify where the cacerts file is (and within my platform certificate)?
But it seems to me wrong ... I've already consumed third party https rest services and never had to specify the certificate path ... this would require me to know structurally some details of a third party server. Am I wrong?
So, I imagine there must be another way to do it ... could anyone help?
Yes, your code specifies a custom path for truststore where the ssl cert is present.
This is the public key shared corresponding to the https protocol for the handshake(either self-signed or signed by a whitelisted CA).
Default path where these get stored is
$JAVA_HOME/jre/lib/security/cacerts
Though above can be overridden.
So in your code, you have overridden the path, to point it where the public key(cert) is already present. Thus it's working for you.
Truststore is just a collection of public keys.
Alternatively, you can import the public key in the default truststore as well to make it work.
In that case, you don't have to explicitly set a different truststore.
There is many ways to do it.
copy your file to $java_home\jre\lib\security\cacerts\ than you don't have to set property manually.
you can also mention path at runtime using
-Djavax.net.ssl.trustStore=/home/user/SSL/mycacerts
-Djavax.net.ssl.keyStore=/home/user/SSL/serverkeystore.jks

Springboot ssl truststore properties not working

I am running a spring boot application which is a webservice client and sends requests to a webservice on a Jboss.
A certificate was added on the jboss and since then i started having exception:
Caused by: 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:387)
So i searched on google on how to communicate with a cert based Jboss and came up with the idea that I needed to create a trust store from the jboss cert and then use that in my application.yaml
server:
port: 7887
address: 127.0.0.1
ssl:
# enabled: true
trust-store: file:config/myapp.truststore
trust-store-password: myappdomain
These didnt work. So i went with more manual and on the grounds approach
I just did the below and this worked. ( for any one having the same issue this works;I added the truststore in the config directory and the config directory was at the same level as the myapp.jar)
java -Djavax.net.ssl.trustStore=config/myapp.truststore -jar myapp.jar
My question: why did the application.yaml configs didnt work. was i missing something.
the above approach works without a password ( may be because the password is the same on keystore and cert in jboss as the trust store password).
Is there any security issue or any kind of issue with the approach that worked. and for future how can i make the yaml configs work.
It is correct as you wrote it, you need to use javax.net.ssl.trustStore and his pair prop javax.net.ssl.trustStorePassword to check the validity of the remote service you are calling.
I understand the 3 options the following way:
server.ssl.key-store => use to authenticate yourself (the server) to other clients calling you
javax.net.ssl.trustStore => use to authenticate servers you are calling as a client from your Spring Boot app.
server.ssl.trust-store => use only if you are using 2-way ssl with Spring, where you authenticate yourself as a client towards other SSL secured server. Probably you will not use this so often when implementing SSL (one way ssl). So stick with the first two and you are good.

Is it possible to merge java\jre\security\lib\cacerts file

In my project,I have integrated Spring Security with CAS server authentication. Now my project is an http application where as the CAS server is an Https application. I was getting following exception after Spring Security and CAS integration: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
In order to solve this error ,I replaced CAS server usr\java\jre\lib\security\cacerts file with my local usr\java\jre\lib\security\cacerts file. After this step the error was gone.
Now I want to deploy my application to some other server. In this new server some other applications are also deployed which may be using different CAS authentication. I cannot directly replace my CAS server cacerts file with this new server cacerts file as in that other application deployed may fail.Right? Can anyone suggest what should I do so that cacerts can be merged,or what should be done? i got to know a command called as keytool but unable to understand how it could be used to merge cacerts file. I dont know how to get my CAS server .cer file,I got to know this could be used in merging,please suggest solution
There is a missunderstanding here.
cacerts is Java's default truststore containing all the trusted certificates for known CA's (Verisign etc). So java can by default trust these certificates same way that your browser does.
This truststore should be used when you want to connect to servers that are signed by these CAs.
In all other cases you are expected to use your own custom truststore so that you can trust specific servers.Actually this is the norm.
So what you should be doing is to load in your code your own truststore and provide that to Java's JSSE to use for authentication during handshake

Java client can't access web service using SSL over HTTPS

We have a simple web application in Java running on WebLogic secured with SSL over https. The name of the server is dev-service1. Access to the web app using a browser with https works fine, however, with a standalone Java client we are getting the following error indicating that the "dev-service1" is not found in the client.jks file.
com.sun.xml.internal.ws.client.ClientTransportException:
HTTP transport error: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException:
No name matching dev-service1 found
at com.sun.xml.internal.ws.transport.http.client.HttpClientTransport.getOutput(HttpClientTransport.java:121)
Do we have to export a new client.jks file from the server.jks file using Java's keytool?
You will need to add the self-signed certificate from the server into your clients truststore.
I would recommend using the InstallCert program that can be found in one of two places.
Quick note. I'm fairly sure that the above programs will NOT add the certificate from the server to your default truststore that ships with java. So you will have to set the -Djavax.net.ssl.trustStore and -Djavax.net.ssl.trustStorePassword VM Arguments in your command line that you use to start your client.

SSL setup on WebSphere 6.1 for Windows

I'm a bit of a newbie when it comes to SSL security on WebSphere.
But basically I am calling a URL from my Java application hosted on WebSphere 6.1. The URL is a web service which is secured via SSL. As an example my URL is:
https://servername:portname/service
I call the web service using cURL using:
--cert test.cer --key
test-privkey.pem --pass "Password"
i.e. I have a .CER file and a .PEM file.
Please could someone advise how I configure WebSphere (through the Admin console) to secure "https://servername:portname/service" using the CER file and PEM file I have.
Thank you.
Whenever using a SSL URL, the JVM tries to recognize the certificate based on its trust store. The truststore file is named 'cacerts' and is present in the java/jre/lib/security folder.For the Webapp to recognize the SSL certificate, the root certificates* of the service must be imported into the cacerts store. This can be done with the help of 'keytool -import' in the java/jre/bin folder.
http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/tsec_sslexchangesigncerts.html
Whenever using a SSL URL, the JVM tries to recognize the certificate based on its trust store. The truststore file is named 'cacerts' and is present in the java/jre/lib/security folder.For the Webapp to recognize the SSL certificate, the root certificates* of the service must be imported into the cacerts store. This can be done with the help of 'keytool -import' in the java/jre/bin folder.
Root certificate is the Certifying Authority [CA] of a service i.e the Organization that provides the SSL certificate will have a CA cert to identify itself.
Let me know if you need more details.

Categories

Resources