JBoss.orgCommunity Documentation

Chapter 12.  Encrypting EJB connections with SSL

12.1. SSL Encryption overview
12.1.1. Key pairs and Certificates
12.2. Generate encryption keys and certificate
12.2.1. Generate a self-signed certificate with keytool
12.2.2. Configure a client to accept a self-signed server certificate
12.3. EJB3 Configuration
12.3.1. Create a secure remoting connector for EJB3
12.3.2. Configure EJB3 Beans for SSL Transport
12.4. EJB2 Configuration

JBoss Application Server uses a socket-based invoker layer for Remote Method Invocation (RMI) of EJB2 and EJB3 Beans. This network traffic is not encrypted by default. Follow the instructions in this chapter to use Secure Sockets Layer (SSL) to encrypt this network traffic.

Procedure 12.1. Configure SSL for EJB3 Overview

  1. Generate encryption keys and certificate

  2. Configure a secure remote connector

  3. Annotate EJB3 beans that will use the secure connector

Procedure 12.2. Configure SSL for EJB2 Overview

  1. Generate encryption keys and certificate

  2. Configure Unified Invoker for SSL

Secure Sockets Layer (SSL) encrypts network traffic between two systems. Traffic between the two systems is encrypted using a two-way key, generated during the handshake phase of the connection and known only by those two systems.

For secure exchange of the two-way encryption key, SSL makes use of Public Key Infrastructure (PKI), a method of encryption that utilizes a key pair. A key pair consists of two separate but matching cryptographic keys - a public key and a private key. The public key is shared with others and is used to encrypt data, and the private key is kept secret and is used to decrypt data that has been encrypted using the public key. When a client requests a secure connection a handshake phase takes place before secure communication can begin. During the SSL handshake the server passes its public key to the client in the form of a certificate. The certificate contains the identity of the server (its URL), the public key of the server, and a digital signature that validates the certificate. The client then validates the certificate and makes a decision about whether the certificate is trusted or not. If the certificate is trusted, the client generates the two-way encryption key for the SSL connection, encrypts it using the public key of the server, and sends it back to the server. The server decrypts the two-way encryption key, using its private key, and further communication between the two machines over this connection is encrypted using the two-way encryption key.

On the server, public/private key pairs are stored in a key store, an encrypted file that stores key pairs and trusted certificates. Each key pair within the key store is identified by an alias - a unique name that is used when storing or requesting a key pair from the key store. The public key is distributed to clients in the form of a certificate, a digital signature which binds together a public key and an identity. On the client, certificates of known validity are kept in the default key store known as a trust store.

CA-signed and self-signed certificates

Public Key Infrastructure relies on a chain of trust to establish the credentials of unknown machines. The use of public keys not only encrypts traffic between machines, but also functions to establish the identity of the machine at the other end of a network connection. A "Web of Trust" is used to verify the identity of servers. A server may be unknown to you, but if its public key is signed by someone that you trust, you extend that trust to the server. Certificate Authorities are commercial entities who verify the identity of customers and issue them signed certificates. The JDK includes a cacerts file with the certificates of several trusted Certificate Authorities (CAs). Any keys signed by these CAs will be automatically trusted. Large organizations may have their own internal Certificate Authority, for example using Red Hat Certificate System. In this case the signing certificate of the internal Certificate Authority is typically installed on clients as part of a Corporate Standard Build, and then all certificates signed with that certificate are trusted. CA-signed certificates are best practice for production scenarios.

During development and testing, or for small-scale or internal-only production scenarios, you may use a self-signed certificate. This is certificate that is not signed by a Certificate Authority, but rather with a locally generated certificate. Since a locally generated certificate is not in the cacerts file of clients, you need to export a certificate for that key on the server, and import that certificate on any client that will connect via SSL.

The JDK includes keytool, a command line tool for generating key pairs and certificates. The certificates generated by keytool can be sent for signing by a CA or can be distributed to clients as a self-signed certificate.

The keytool command, part of the JDK, is used to generate a new key pair. Keytool can either add the new key pair to an existing key store, or create a new key store at the same time as the key pair.

This key pair will be used to negotiate SSL encryption between the server and remote clients. The following procedure generates a key pair and stores it in a key store called localhost.keystore. You will need to make this key store available to the EJB3 invoker on the server. The key pair in our example will be saved in the key store under the alias 'ejb-ssl'. We will need this key alias, and the key pair password you supply (if any), when configuring the EJB3 Remoting connector in Section 12.3.1, “Create a secure remoting connector for EJB3”.

Note that if no key store is specified on the command line, keytool will add the key pair to a new key store called keystore in the current user's home directory. This key store file will be a hidden file.

Any client machine that will make remote method invocations over SSL needs to trust the certificate of the server. Since the certificate we generated is self-signed, and has no chain of trust to a known certificate authority, the client must be explicitly configured to trust the certificate or the connection will fail. Configuring a client to trust a self-signed certificate requires importing the self-signed server certificate to a trust store on the client.

A trust store is a key store that contains trusted certificates. Certificates that are in the local trust store will be accepted as valid. If your server uses a self-signed certificate then any clients that will make remote method calls over SSL must have that certificate in their trust store. You must export your public key as a certificate, and then import that certificate to the trust store on those clients.

The certificate created in Section 12.2.1.2, “Export a self-signed certificate” must be copied to the client in order to perform the steps detailed in Import the certificate to the trust store "localhost.truststore".

As with the key store, if the trust store specified does not already exist, it will be created. However, in contrast with the key store, there is no default trust store, and one must be specified.

Configure Client to use localhost.truststore

Now that you have imported the self-signed server certificate to a trust store on the client, you must instruct the client to use this trust store. This is done by passing the localhost.truststore location to the application using the javax.net.ssl.trustStore property, and the trust store password using the javax.net.ssl.trustStorePassword property. Example 12.1, “Invoking the com.acme.Runclient application with a specific trust store” is an example commandline that would be used to invoke the application com.acme.RunClient, which will make remote method calls to an EJB on a JBoss Application Server.


The file ejb3-connectors-jboss-beans.xml in a JBoss Application Server profile's deploy directory contains JBoss Remoting connector definitions for EJB3 remote method invocation. Example 12.2, “Sample Secure EJB3 Connector” is a sample configuration that defines a secure connector for EJB3 using the key pair created in Generate a new key pair and add it to the key store "localhost.keystore". The keyPassword property in the sample configuration is the key pair password that was specified when the key pair was created.


The sample configuration will create a connector that listens for SSL connections on port 3843. This port will need to be opened on the server firewall for access by clients.

All EJB3 beans use the unsecured RMI connector by default. In order to enabled a bean to be invoked via SSL, the bean needs to be annotated with @org.jboss.annotation.ejb.RemoteBinding.

The annotation in Example 12.3, “EJB3 bean annotation to enable secure remote invocation” will bind an EJB3 bean to the JNDI name StatefulSSL. The proxy implementing the remote interface, returned to a client when the bean is requested from JNDI, will communicate with the server via SSL.


Note

In Example 12.3, “EJB3 bean annotation to enable secure remote invocation” the IP address is specified as 0.0.0.0, meaning "all interfaces". This should be changed in practice to the value of the ${jboss.bind.address} system property.

Enabling both secure and insecure invocation of an EJB3 bean

You can enable both secure and insecure remote method invocation of the same EJB3 bean. Example 12.4, “EJB3 Bean annotation for both secure and insecure remote invocation” demonstrates the annotations to do this.


If a client requests StatefulNormal from JNDI, the returned proxy implementing the remote interface will communicate with the server via the unencrypted socket protocol; and if StatefulSSL is requested, the returned proxy implementing the remote interface will communicate with the server via SSL.

EJB2 remote invocation uses a single unified invoker, which runs by default on port 4446. The configuration of the unified invoker used for EJB2 remote method invocation is defined in the deploy/remoting-jboss-beans.xml file of a JBoss Application Server profile. Add the following SSL Socket Factory bean and an SSL Domain bean in this file.


Configure SSL Transport for Beans

In the deploy/remoting-jboss-beans.xml file in the JBoss Application Server profile, update the code to reflect the information below: