We help IT Professionals succeed at work.

2 way SSL setup with java client running on Tomcat server calling webservice hosted on Websphere server.

I want to know if this is possible to have 2 way SSL with tomcat acting as client to websphere server. I have configured key and trust store correctly in server.xml of tomcat and enabled SSL on both tomcat and Websphere.

My problem is : when challenged by websphere server to present client certificate , tomcat does not present a client certificate.

I know that SSL is configured correctly in tomcat as when I open a servlet hosted on tomcat in Internet explorer, tomcat does present its server certificate.
When this servlet internally call web service hosted on websphere server, websphere server presents its server certificate and demand tomcat client certificate which tomcat does not present thus causing  the SSL handshake failure.  

Thanks,
Satish
Comment
Watch Question

mccarlIT Business Systems Analyst / Software Developer
Top Expert 2015

Commented:
with tomcat acting as client to websphere server
So, tomcat doesn't have anything built-in to provide service for calling out to web services. Therefore, you must (knowingly or unknowingly) be using some client library to make the calls to websphere in your code. Do you know what this might be? ie. it could be something like apache commons http components, Spring libraries, or perhaps just plain old java.net.HttpConnection's

Because the is no interaction between the code that is acting as a client calling out to websphere and Tomcat itself, that is why the client is not presenting any certificate. You will need to configure this in your http client library and hence that is why I am asking the question above, so that we can work out how you need to configure it.
Exec Consultant
Distinguished Expert 2019
Commented:
This article is in relevant to your case (note they are using self-signed cert though but should not matter), may be old article but the steps should not differs. http://kadarla.blogspot.sg/2009/04/2-way-ssl-between-two-application.html

At client end, I assumed the following has been configured for the two Java option as example..
set JAVA_OPTS="-DJavax.net.ssl.trustStore=C:\path\to\keystore.key" set JAVA_OPTS="-DJavax.net.ssl.trustStorePassword=****"

Do note that when Tomcat is started it initiates the catalina.bat file (normally found in Tomcat\bin folder) and this file determines whether a "setenv.bat" file exists (typically) and if exist, runs this file to set the Java options above. This is more of Tomcat set up as a Windows service case.

Author

Commented:
Thanks. I found that I do  not need to run tomcat in SSL mode . I also removed configuration of keystore and trust store  from server.xml and ran tomcat in http ( port 8080).

I  set the property in my java client code ( running on tomcat- no apache web server required).
The only change I made was to make sure all the websphere server certificates ( certificate chains including all the root certificates ) are imported in tomcat truststore file. Once I  imported websphere certificate chain, SSL handshake between  java client running on tomcat  and  Websphere server  was successful.

Thanks to all for your suggestions.
 
Here is my code ( works perfectly):
       


           String urlStr = "https://someSecureURL.com";
             
            System.setProperty("javax.net.ssl.trustStore", "C:\\Users\\DIR\\keystore1.jks");        
            System.setProperty("javax.net.ssl.trustStorePassword", "password1");                
             
     
            System.setProperty("javax.net.ssl.keyStore", "C:\\Users\\DIR\\keystore2.jks");        
            System.setProperty("javax.net.ssl.keyStorePassword", "password2");
           
            SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
            URL url = new URL(urlStr);

           HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
           conn.setConnectTimeout(3000);
           conn.setReadTimeout(3000);
           conn.setUseCaches(false);
           conn.setRequestMethod("GET");
           conn.setSSLSocketFactory(sslsocketfactory);
           InputStream inputstream = conn.getInputStream();
           InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
           BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

           String string = null;
           while ((string = bufferedreader.readLine()) != null) {
               System.out.println("Received " + string);
           }
           conn.disconnect();
btanExec Consultant
Distinguished Expert 2019

Commented:
thanks for sharing

Author

Commented:
I've requested that this question be closed as follows:

Accepted answer: 0 points for COUTLOOK's comment #a40674742

for the following reason:

I was able to make it work after importing certificate chain.
btanExec Consultant
Distinguished Expert 2019

Commented:
noted if we have assisted in any means will appreciate your noting, regardless, thanks!

Author

Commented:
On further research , I found that there is no code change required  for tomcat to send client certificate to websphere for SSL handshake.

we just need to set JAVA_OPTS  in catalina.bat file and it takes care of handshake at containter level.

Please note that code change approach uses dos format for file path  

System.setProperty("javax.net.ssl.keyStore", "C:\\Users\\DIR\\keystore2.jks");        

but catalina.bat change use UNIX format for file path as shown below:
set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG% -Djavax.net.ssl.trustStore="C:/Users/keystore1.jks" -Djavax.net.ssl.trustStorePassword="password1" -Djavax.net.ssl.keyStore="C:/Users//keyStore2.jks" -Djavax.net.ssl.keyStorePassword="password2"

Hope this helps.
btanExec Consultant
Distinguished Expert 2019

Commented:
then it would mean the solution is already in my reply, isnt it (which is why I am curious how would it have work)?
http://www.experts-exchange.com/Programming/Languages/Java/Q_28638149.html#a40672751

Author

Commented:
Yes. Much appreciated. Somehow it did not work for me. One reason I can think is location of quotes:

set JAVA_OPTS="-DJavax.net.ssl.trustStore=C:\path\to\keystore.key"

vs  

set JAVA_OPTS=-DJavax.net.ssl.trustStore="C:\path\to\keystore.key"


I spent 3 days researching  this and like the expert forum here very much.

I hope this will save others some time.


Thanks all for your opinion.
btanExec Consultant
Distinguished Expert 2019

Commented:
hope at least it has assisted then, regardless - thanks!

Author

Commented:
Yes. It definitely helped. Thanks  a lot !
btanExec Consultant
Distinguished Expert 2019

Commented:
thanks for sharing again