Enterprise Java

SSL encrypted EJB calls with JBoss AS 7

Encrypting the communication between client and server provides improved security and privacy protection for your system. This can be an important requirement by the customer, especially if client or server need to work in an unprotected network.

This article shows you how to setup SSL encrypted EJB calls in JBoss AS 7.

Server

There are only two things that need to be done on server side:
 
 

  1. creating a key store with the privat/public pair of keys for the encryption and
  2. referencing the key store in the server configuration.

The source code of your application stays the same with or without encryption.

Creating the keys

Java provides the tool keytool which we will use to manage the key store and to create the private/public pair of keys. The example below creates a pair of 1024 bit keys using the RSA algorithm and adds them to the key store server.keystore. The key store will be created if it does not exist.

keytool -genkey -alias jboss -keyalg RSA -keysize 1024 -keystore server.keystore -validity 365 

        -keypass 123456 -storepass 123456 -dname "CN=localhost, O=thoughts-on-java.org"

We will need to provide this key store to the JBoss application server. Therefore I prefer to store it in the JBoss configuration directory. But you can store it where ever you want as long as the JBoss server can access it.

Server configuration

Now we have to reference the keystore in the JBoss configuration. Therefore we add a server-identities element to the security realm configuration of the application realm.

The following snippet shows an example configuration using the standard ApplicationRealm configuration and a server.keystore file located in the JBoss configuration directory:

<management>
   <security-realms>
      <security-realm name="ManagementRealm">
         <authentication>
            <properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
         </authentication>
      </security-realm>
      <security-realm name="ApplicationRealm">
         <server-identities>
            <ssl>
               <keystore path="server.keystore" relative-to="jboss.server.config.dir" password="123456"/>
            </ssl>
         </server-identities>
         <authentication>
            <properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
         </authentication>
      </security-realm>
   </security-realms>

   ...

This is all that’s needs to be done on server side.

Client

On client side, we need to do the following things:

  1. import the public key of the server into the client key store,
  2. define SSL encryption in the EJBClientProperties and
  3. provide the location and password of a key store with the public key JVM arguments.

Importing the key

First we need to export the public key of the key pair we added to the server key store. This can be done with the keytool, too:

keytool -export -keystore server.keystore -alias jboss -file server.cer -keypass 123456 -storepass 123456

The key store will be created if it does not exist.

OK, now we can add the key to the client keystore:

keytool -import -trustcacerts -alias jboss -file server.cer -keystore client.keystore -keypass 123456 -storepass 123456

EJBClientProperties

There is no big difference in the EJBClientProperties. The properties remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED and remote.connection.default.connect.options.org.xnio.Options.SSL_STARTTLS need to be set to true. The rest stays unchanged.

The following snippet shows the creation of an SSL encrypted connection to the server and the lookup of an SLSB.

// define EJB client properties
final Properties props = new Properties();
// define SSL encryption
props.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED",
  "true");
props.put("remote.connection.default.connect.options.org.xnio.Options.SSL_STARTTLS",
  "true");
// connection properties
props.put("remote.connections", "default");
props.put("remote.connection.default.host", "localhost");
props.put("remote.connection.default.port", "4447");
// user credentials
props.put("remote.connection.default.username", "test");
props.put("remote.connection.default.password", "1234");

props.put("remote.connection.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS",
  "JBOSS-LOCAL-USER");
props.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT",
  "false");
props.put("remote.connection.default.connect.options.org.jboss.remoting3.RemotingOptions.HEARTBEAT_INTERVAL",
  "600000");

// create EJB client configuration
final EJBClientConfiguration clientConfiguration = new PropertiesBasedEJBClientConfiguration(
  props);

// create and set a context selector
final ContextSelector<EJBClientContext> contextSelector = new ConfigBasedEJBClientContextSelector(
  clientConfiguration);
EJBClientContext.setSelector(contextSelector);

// create InitialContext
final Hashtable<Object, Object> contextProperties = new Hashtable<>();
ejbURLContextFactory.class.getName();
contextProperties.put(Context.URL_PKG_PREFIXES,
  "org.jboss.ejb.client.naming");
InitialContext initialContext = new InitialContext(contextProperties);

// lookup SLSB
GreeterRemote greeter = (GreeterRemote) initialContext
  .lookup("ejb:/test/Greeter!blog.thoughts.on.java.ssl.remote.GreeterRemote");
Assert.assertEquals("Hello World!", greeter.greet("World"));

JVM arguments 

OK, now we are nearly done. The only thing missing is the reference to the client key store. This can be done with the JVM arguments javax.net.ssl.trustStore for the location and javax.net.ssl.trustStorePassword for the password of the key store, e.g.:

-Djavax.net.ssl.trustStore=src\test\resources\client.keystore -Djavax.net.ssl.trustStorePassword=123456

This is all needs to be done to setup SSL encrypted EJB calls with JBoss AS 7.

Troubleshooting

If there are any communication problems, you can set -Djavax.net.debug=true to enable debug messages.

Conclusion

In this article we had a look at the configuration and code changes to setup encrypted EJB calls with JBoss AS 7. It can be done in a few minutes and provides an improved security and privacy protection to your communication.

Reference: SSL encrypted EJB calls with JBoss AS 7 from our JCG partner Thorben Janssen at the Some thoughts on Java (EE) blog.

Thorben Janssen

Thorben Janssen is a senior developer with more than 10 years of experience in Java EE development and architecture. During these years he acted as developer, architect, project and/or technical lead to create high available, clustered mobile billing solutions and laboratory information management systems.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button