Showing posts with label SSL. Show all posts
Showing posts with label SSL. Show all posts

Monday, April 13, 2015

Java 7 and TLSv1.2 - supported, but not enabled by default

Lately, I had to investigate how to make a Java 7 client connect to a server resource (in my case a JMS broker server) using sockets or http traffic over secure TLS v1.2 protocol (and only TLS v1.2... all other communication protocols should be refused). This would all have been a breeze if my client app was on Java 8...but being on Java 7, it was a completely different story.

At first, I thought it'd be easy since my JMS broker server (Terracotta Universal Messaging in this case) already supports TLS v1.2, lets you enforce it through system property (-DSSLProtocols), and also lets you pick which cipher(s) to use. So I thought all I needed was to set that system property on the server side and disable in the UI (called Enterprise Manager) all ciphers for this communication interface BUT the TLS v1.2 ciphers I wanted to use (the "SHA256" cipher suites in this case -- check full list of available ciphers for TLS v1.2 at https://www.openssl.org/docs/apps/ciphers.html)...as shown below in screenshot:


And everything would work fine, right? The client would start the secure handshake with the server, figure out that TLSv1.2 is the only protocol that can be used, and use the right secure protocol version and ciphers as defined by the server.

Well, this theoretical scenario is partially true: Everything is setup properly on the server side, as it rightly says "I only accept TLSv1.2 sessions with the following ciphers". But unfortunately, the Java 7 client does not seem to be able to start a TLSv1.2 secure connection by default (if you're on Java 8, stop reading right now -- unless you're curious of course -- as it would all work fine out of the box)

And yes, after quick research, Java 7 introduced support for TLS v1.2 (refer to http://docs.oracle.com/javase/7/docs/technotes/guides/security/enhancements-7.html) BUT does not enable it by default. In other words, your client app must explicitly specify "TLS v1.2" at SSLContext creation, or otherwise will just not be able to use it.

This is a pretty important nuance that you can test yourself very easily with the following 2 test cases:

1) Output for Gist - Java 7 + SSLContext context = SSLContext.getDefault()
Supported Protocols: 5
 SSLv2Hello
 SSLv3
 TLSv1
 TLSv1.1
 TLSv1.2
Enabled Protocols: 1
 TLSv1
Enabled Ciphers: 80
... list of available ciphers omitted here ...
2) Output for Gist - Java 7 + SSLContext context = SSLContext.getInstance("TLSv1.2")
Supported Protocols: 5
 SSLv2Hello
 SSLv3
 TLSv1
 TLSv1.1
 TLSv1.2
Enabled Protocols: 3
 TLSv1
 TLSv1.1
 TLSv1.2
Enabled Ciphers: 80
... list of available ciphers omitted here ...
So this is great! All you and I need is to update the client app's code to specify TLSv1.2 at SSL Context creation! 
But wait...what if I'm using a client library to perform all that low level SSLContext connection etc...in that case, it's going to be tricky to update the code, unless specifying the SSL protocol versions and ciphers are exposed to client app in some way (eg. system properties).
If you reach this situation, here are 3 solutions I found (well, I found 1 and 3...solution 2 is credited to a smarter developer :) )
1) If all you want is to create a HTTPS connection (over TLSv1.2) from your client app to the server, you're in luck: all you need is add the following 2 system properties to your client app and the SSL context will be created properly as specified:
  • https.protocols ==> -Dhttps.protocols=TLSv1.2 (comma-separated list of you want to use several protocols)
  • https.cipherSuites ==> -Dhttps.cipherSuites=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (comma-separated list of you want to use several ciphers)
2) If you want to use the secure socket protocol (as opposed to HTTPs traffic), the above properties won't work unfortunately...but you could create a "TLSv1.2" SSLContext at application startup and use the "SSLContext.setDefault(ctx)" call to register that new context as the default one.

3) Upgrade your client to JAVA 8, which enables TLSv1.2 protocol by default (at this time, JAVA 8 should be already used anyway, or on most project roadmaps hopefully)

That's it! Another fun investigative work day at the office!

Friday, December 5, 2014

SSL Encryption / Authentication between JBOSS JCA + SoftwareAG webMethods Broker

In our previous post (Integrating SoftwareAG webMethods messaging Broker with JBOSS AS 7 through standard JCA) we created a simple setup to publish and consume JMS messages using JCA Resource Adapter construct on JBOSS AS 7.

This post will extend this simple setup by explaining how to use secure communications (SSL encryption + SSL Authentication) between JBOSS and webMethods Broker.

Please note this post is the 2nd out of the following 3 related posts:
  1. Integrating SoftwareAG webMethods messaging Broker with JBOSS AS 7 through standard JCA
  2. SSL Encryption / Authentication between JBOSS JCA + SoftwareAG webMethods Broker
  3. JBOSS Vault to encrypt JMS password for secure JCA configuration

First, let's assume that you're already a webMethods Broker expert and have already setup your Broker server with the right SSL certificates (and if not, please refer to that "pretty"-screenshots SoftwareAG "techcommunity" document (PDF - 4MB) I was referring to in the previous post -- go to "Configuring SSL Communication / Authentication" on page 13).

And all we need to do now is to have our JBOSS client encrypt all communications and authenticate to Wm Broker over SSL...

It's actually very easy:
All you need to do is add the right system properties for it (jboss admin console at “profile > General Configuration > System Properties”)...and the wM Broker client library will take care of the rest without changing anything in the code or configuration!

Here are the needed properties:
  • com.webmethods.jms.username
  • com.webmethods.jms.password
  • com.webmethods.jms.ssl.keystore
  • com.webmethods.jms.ssl.keystoretype
  • com.webmethods.jms.ssl.truststore
  • com.webmethods.jms.ssl.truststoretype
All these values must match the keystore and trustore you used on the wM Broker server side...

Important notes:
  • keystore should be of type "PKCS12" (keystoretype=PKCS12)
  • trustore of type "JKS" (truststoretype=JKS)
  • username / password must match (of course) the ones used by your keystore...

That's it: once those properties are set, you should be able to verify in the wM Broker client sessions are indeed using SSL encryption + SSL authentication...