Using SSL

Introduction

SwiftMQ's sockets for blocking I/O are created by configurable socket factories. There are 2 predefined socket factories included in the distribution:

  • com.swiftmq.net.PlainSocketFactory
  • com.swiftmq.net.JSSESocketFactory

The first one creates plain sockets and the second one SSL sockets by using the Java Secure Socket Extension (JSSE). Both factories are specified for JMS and Routing listeners. They are passed over to JMS clients with the connection factory they lookup through JNDI.

It is further possible to create own socket factories by implementing the com.swiftmq.net.SocketFactory interface.

Click here to view the Javadoc.

Using the JSSE Socket Factory

This socket factory enables you to use SSL via JMS and Routing connections. The following possibilities exists to use SSL:

  • Without certificates by using an anonymous cipher suite (default).
  • With self-generated or purchased certificates and server authentication.
  • With self-generated or purchased certificates and server/client authentication.

Without Certificates by using an anonymous Cipher Suite (default) up to SwiftMQ 9.7.1 and JDK 1.7

This mode is used by default and enables you to use SSL with an anonymous cipher suite out of the box without generating and configuring certificates. You don't have to specify any system properties, however, the following are used and can be changed:

System Property Description Default
swiftmq.jsse.anoncipher.enabled Enables/disables use of anonymous cipher suites true
swiftmq.jsse.anoncipher.name Name of the anonymous cipher suite SSL_DH_anon_WITH_RC4_128_MD5

Therefore, if you use the JSSE socket factory without specifying the above system properties, the anonymous cipher suite "SSL_DH_anon_WITH_RC4_128_MD5" is used.

Look here for other anonymous cipher suites.

Without Certificates by using an anonymous Cipher Suite (default) starting at SwiftMQ 9.7.2 and JDK 1.8

SSLv3 has been disabled in JDK 1.8 and later due to the POODLE exploit and the anonymous SSL cipher suite mentioned in the previous chapter will not work anymore. JDK 1.8+ will now use TLS as default. SwiftMQ 9.7.2 has changed the JSSESocketFactory to use TLS anonymous cipher suites.

The following system properties can be configured:

System Property Description Default
swiftmq.jsse.anoncipher.enabled Enables/disables use of anonymous cipher suites true
swiftmq.jsse.anoncipher.name Name of the anonymous cipher suite none

If property swiftmq.jsse.anoncipher.name is not set (default), the JSSESocketFactory enables all cipher suites starting with "TLS_" and which contains "_anon_". These are:

  • TLS_DH_anon_WITH_AES_128_CBC_SHA256
  • TLS_ECDH_anon_WITH_AES_128_CBC_SHA
  • TLS_DH_anon_WITH_AES_128_CBC_SHA
  • TLS_ECDH_anon_WITH_RC4_128_SHA
  • TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA
  • TLS_ECDH_anon_WITH_NULL_SHA

Look here for other anonymous cipher suites.

If you want to reduce it to a specific anonymous cipher suite, you need to set it via system property swiftmq.jsse.anoncipher.name which must contain a single name. This is also the case if you run the SwiftMQ Universal Router on JDK 1.8+ and a client on a lower JDK version. In that case pick one of the above anonymous cipher suites and set it via swiftmq.jsse.anoncipher.name.

With self-generated or purchased Certificates and Server Authentication.

In this mode, the server (router) presents a certificate to the JMS client during connect and the client trust it or not. When using JSSE for Routing connections, the server in the sense of JSSE is the router with the Routing listener and the client is the router with the Routing connector.

First of all, we need a certificate and use "keytool" (included in the JDK) to create it:

      E:\swiftmq_3_0_1_eval\scripts\win32>keytool -genkey -alias swiftmq
                                       -keystore ./routercerts -storepass secret1234
      What is your first and last name?
        [Unknown]:  Kai Wiesinger
      What is the name of your organizational unit?
        [Unknown]:  Software Development
      What is the name of your organization?
        [Unknown]:  IIT Software GmbH
      What is the name of your City or Locality?
        [Unknown]:  Bremen
      What is the name of your State or Province?
        [Unknown]:  Bremen
      What is the two-letter country code for this unit?
        [Unknown]:  DE
      Is <CN=Kai Wiesinger, OU=Software Development, O=IIT Software GmbH, L=Bremen, ST=Bremen, C=DE> correct?
        [no]:  yes

      Enter key password for <swiftmq>
              (RETURN if same as keystore password):

      E:\swiftmq_3_0_1_eval\scripts\win32>

Now we have a certificate, stored in the key store "routercerts" in the current directory.

Next step is to extract the certificate and move it to the client's trust store:

      E:\swiftmq_3_0_1_eval\scripts\win32>keytool -export -alias swiftmq \
      -keystore ./routercerts -storepass secret1234 -file router.cer
      Certificate stored in file <router.cer>

      E:\swiftmq_3_0_1_eval\scripts\win32>keytool -import -alias swiftmq \
      -keystore ./clienttrustcerts -storepass secret1234 -file router.cer
      Owner: CN=Kai Wiesinger, OU=Software Development, O=IIT Software GmbH, L=Bremen, ST=Bremen, C=DE
      Issuer: CN=Kai Wiesinger, OU=Software Development, O=IIT Software GmbH, L=Bremen, ST=Bremen, C=DE
      Serial number: 3c9764c5
      Valid from: Tue Mar 19 17:18:13 CET 2002 until: Mon Jun 17 18:18:13 CEST 2002
      Certificate fingerprints:
               MD5:  B2:AD:C6:15:77:DD:7A:28:1A:EA:35:BC:2C:DF:40:D1
               SHA1: D5:20:2C:68:65:8E:35:39:C8:C5:FA:50:04:8A:0E:9D:34:C0:FF:8A
      Trust this certificate? [no]:  yes
      Certificate was added to keystore

      E:\swiftmq_3_0_1_eval\scripts\win32>

The certificate with alias "swiftmq" is now stored in the trust store "clienttrustcerts" in the current directory.

The last step is to modify the command line of the router and the JMS client(s). The router command line needs to have the following system properties to be defined:

      -Dswiftmq.jsse.anoncipher.enabled=false
      -Djavax.net.ssl.keyStore=e:/swiftmq_3_0_1_eval/scripts/win32/routercerts
      -Djavax.net.ssl.keyStorePassword=secret1234

The JMS client(s) needs to have the following system properties to be defined:

      -Dswiftmq.jsse.anoncipher.enabled=false
      -Djavax.net.ssl.trustStore=e:/swiftmq_3_0_1_eval/scripts/win32/clienttrustcerts
      -Djavax.net.ssl.keyStorePassword=secret1234

Finally, start the router and the JMS client(s) and connect. The router will present the certificate to the client(s) which will check the trust store for this certificate. Thereafter, the connection is established. The same procedure must be done when using Routing connections with SSL and server authentication. The client in that case is the router with the Routing connector.

A more detailed description can be found here.

With self-generated or purchased Certificates and Server and Client Authentication.

In this mode, the server (router) presents a certificate to the JMS client during connect and the client trust it or not. Then, the server requests a certificate from the client and trust it or not. That way, both sides must have a valid certificate which must be trusted from the other side to establish a connection.

The procedure to self-generate a server certificate is the same as mentioned in the previous section. Plus: The client certificate is generated on the client side, stored in the client's key store, exported to a file and imported into the server's trust store. Thus, both sides have a key store and a trust store.

The router needs the following system properties to be specified on the command line:

      -Dswiftmq.jsse.anoncipher.enabled=false
      -Dswiftmq.jsse.clientauth.enabled=true
      -Djavax.net.ssl.trustStore=e:/swiftmq_3_0_1_eval/scripts/win32/routertrustcerts
      -Djavax.net.ssl.keyStore=e:/swiftmq_3_0_1_eval/scripts/win32/routercerts
      -Djavax.net.ssl.keyStorePassword=secret1234

Note that "swiftmq.jsse.clientauth.enabled=true" enables the client authentication, that is, the router requests a certificate from the client.

The JMS client(s) needs to have the following system properties to be defined:

      -Dswiftmq.jsse.anoncipher.enabled=false
      -Djavax.net.ssl.trustStore=e:/swiftmq_3_0_1_eval/scripts/win32/clienttrustcerts
      -Djavax.net.ssl.keyStore=e:/swiftmq_3_0_1_eval/scripts/win32/clientcerts
      -Djavax.net.ssl.keyStorePassword=secret1234

Finally, start the router and the JMS client(s) and connect. Both side will present their certificates to each other and the connection is established if both sides trust the presented certificates.