Using SSL with GlassFish v2

By Kumar Jayanti

Most enterprise applications need to run in a secure environment. Transport Layer Security (TLS)/Secure Sockets Layer (SSL) is a point-to-point secure transport mechanism that can be used for authenticating messages exchanged between a client and a server, and for ensuring message integrity and confidentiality. TLS/SSL (or in this tip, simply "SSL") meets the security requirements of most enterprise application environments, and is widely adopted.

However to participate in SSL-secured message exchanges, the server needs to be enabled as an SSL server. This tip will show you how to enable the GlassFish v2 application server as an SSL server.

In order to follow the steps, you need to understand some basic concepts in SSL such as keys and certificates and understand a concept in GlassFish v2 called profiles.

Keys and Certificates

Two important concepts in SSL are keys and certificates. Keys are used to establish trust and privacy in transactions between the client and the server. SSL uses public key cryptography, which is based on key pairs. Key pairs contain one public key and one private key. If data is encrypted with one key, it can be decrypted only with the other key of the pair.

Certificates are used for authentication. To use SSL, the server must have an associated certificate for each client IP address with which it can connect. The certificate identifies the owner of the server site and provides related information. The certificate is digitally and cryptographically signed by its owner. For sites in which authentication is important, a certificate can be purchased from a well-known trusted certificate authority (CA). However, if authentication is not really a concern, a site can use a self-signed certificate.

GlassFish v2 Profiles

GlassFish v2 supports various usage profiles. Each profile presets configuration parameters for the application server to optimize it for a particular type of use. The three profiles are developer, cluster, and enterprise.

The developer profile optimizes GlassFish v2 for use in a development environment. This means that the configuration parameters support objectives such as fast startup, but don't support things like logging or session replication. The cluster profile sets configuration parameters that enable cluster creation and session replication. A cluster is a group of GlassFish v2 instances that can be managed and monitored as a single logical entity. The enterprise profile optimizes GlassFish v2 for a production environment. It supports things like logging and other security-related features.

Enabling the GlassFish v2 Application Server as an SSL Server

The steps to enable the GlassFish v2 as an SSL server depend on the profile used for the application server. Let's first examine the process if the developer profile is used. Then let's examine the process when the enterprise profile is used.

When the Developer Profile is Used

Recall that a GlassFish v2 profile presets configuration parameters for a particular type of use. One of those parameters is Security Store, which identifies how security and trust-related artifacts such as certificates and keys are stored. For the developer profile, the Security Store value is set to JKS. In this case, certificates and keys for the server are stored in a Java keystore file (keystore.jks) and certificates issued by trusted CAs are stored in a certificates file (cacerts.jks).

When you install GlassFish v2, it creates a default self-signed certificate as the server certificate. However, if authentication is important in your site, you need to replace the self-signed certificate with a digitally-signed certificate from a CA. This section describes how to replace the self-signed certificate, how to obtain a server certificate from a CA, and how to import the server certificate into the keystore.

The steps described below use keytool, a key and certificate management tool. Keytool is available in various versions of the Java Platform, Standard Edition (Java SE) Development Kit (jdk). However Java SE 6 added some required functions to keytool. The instructions below are based on the jdk 6 version of keytool. For detailed information about keytool, see JDK Tools and Utilities.

Here are the instructions for enabling GlassFish v2 as an SSL server when the application server is configured with the developer profile.

  1. Delete the default self-signed certificate by issuing the following command (note that the commands in this and subsequent steps are shown on multiple lines for formatting purposes):

           keytool -delete -alias s1as -keystore keystore.jks 
           -storepass <store_passwd>

    where <store_passwd> is the password for the keystore, for example, "mypass". Note that s1as is the default alias of the GlassFish v2 keystore.

  2. Generate a new key pair for the application server by issuing the following command:

          keytool -genkeypair -keyalg <key_alg> 
          -keystore keystore.jks -validity <val_days> -alias s1as 

    where <key_alg> is the algorithm to be used for generating the key pair, for example RSA, and <val_days> is the number of days that the certificate should be considered valid, for example, 365.

    Note that in addition to generating a key pair, the command wraps the public key into a self-signed certificate and stores the certificate and the private key in a new keystore entry identified by the alias.

    It's important to ensure that the name of the certificate matches the fully-qualified hostname of your site. If the names don't match, clients connecting to the server will see a security alert stating that the name of the certificate does not match the name of the site. You should notice that the name of the default self-signed certificate matches the fully-qualified hostname.

  3. Generate a Certificate Signing Request (CSR) by issuing the following command:

          keytool -certreq -alias s1as -file <certreq_file> 
          -keystore keystore.jks -storepass <store_passwd>

    where <certreq_file> is the file in which the CSR is stored, for example, s1as.csr, and <store_passwd> is the password for the keystore, for example, changeit.

  4. Submit the CSR to a CA such as VeriSign. In response, you should receive a signed server certificate. Make sure to import into your browser the CA certificate of the CA and any intermediate certificates indicated by the CA in the reply.

  5. Store the signed server certificate from the CA including the markers -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- into a file such as s1as.cert. Download the CA certificate and any intermediate CA certificates and store them in local files. Refer to your browser documentation on how to import the CA and intermediate CA certificates into the browser. The CA may provide information on how to import the CA certificates into various browsers such as Mozilla and Internet Explorer.

  6. Replace the original self-signed certificate with the certificate you obtained from the CA (stored in a file such as s1as.cert). You can use keytool to do this, as follows:
       keytool -import -v -alias s1as -file s1as.cert 
       -keystore keystore.jks -storepass <store_passwd>
    

    When you import the certificate using the same original alias "s1as", keytool treats it as a command to replace the original certificate with the certificate obtained as reply to a CSR.

    After running the program, you should see that the certificate s1as in the GlassFish keystore is no longer the original self-signed certificate, but is now the response certificate from the CA. Here is an example that compares an original s1as certificate with a new s1as certificate obtained from VeriSign:

    Original s1as (self-signed):

    Owner: CN=KUMAR, OU=Sun Java System Application Server, O=Sun
    Microsystems, L=Santa Clara, ST=California, C=US
    Issuer: CN=KUMAR, OU=Sun Java System Application Server, O=Su
    n Microsystems, L=Santa Clara, ST=California, C=US
    Serial number: 472acd34
    Valid from: Fri Nov 02 12:39:40 GMT+05:30 2007 until: Mon Oct
    30 12:39:40 GMT+05:30 2017

    New s1as (contains signed cert from CA):

    Owner: CN=KUMAR, OU=Terms of use at www.verisign.com/cps/test
    ca (c)05, OU=Sun Java System Application Server, O=Sun Micros
    ystems, L=Santa Clara, ST=California, C=US
    Issuer: CN=VeriSign Trial Secure Server Test CA, OU=Terms of
    use at https://www.verisign.com/cps/testca (c)05, OU="For Test
    Purposes Only. No assurances.", O="VeriSign, Inc.", C=US
    Serial number: 1375de18b223508c2cb0123059d5c440
    Valid from: Sun Nov 11 05:30:00 GMT+05:30 2007 until: Mon Nov
    26 05:29:59 GMT+05:30 2007

After performing these steps, you can restart GlassFish v2 and use the signed server certificate issued by the CA.

When the Cluster Profile is Used

You perform the same steps to enable GlassFish v2 as an SSL server when the application server is configured with the cluster profile as you do for a developer profile. However, in this case you need to ensure that the same server key in replicated in all the application server instances in the cluster.

When the Enterprise Profile is Used

The Security Store parameter value for the enterprise profile is NSS, which stands for Network Security Services. In an NSS security infrastructure there is no JKS keystore and so there is no default GlassFish keystore.

For the most part, the steps to enable the GlassFish v2 application server as an SSL server are the same when the enterprise profile is used as when the developer profile is used. However there are two differences. The first difference pertains to the first step of the process. Because there is no JKS keystore, you start the process with an empty keystore (keystore.jks). The second difference pertains to the last step of the process. Instead of importing the resulting signed certificate into the JKS keystore, you import it into the NSS store. In other words, to enable the GlassFish v2 application server as an SSL server, you perform the same steps as in the When the Developer Profile is Used section, but you start with an empty keystore, and you replace step 6 in that section with the following steps:

  1. Export the private key for the server certificate from the keystore in Privacy Enhanced Mail (PEM) format by issuing the following command:

          keyexport.bat -keyfile serverkey.pem 
          -keystore keystore.jks -storepass changeit -alias s1as 

    The command invokes the keyexport utility. You can find the keyexport in the keyexport package, which you can download from the XWSS downloads page in Project Metro

    In response you will be prompted for the keystore password. The keystore password is the same as the key password, so you can reply by simply pressing the return key.

    This creates a serverkey.pem file which contains the server private key under the markers -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY-----.

  2. Append the signed certificate reply from the CA, including the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- markers, to the servercert.pem file. Append the reply just below the END PRIVATE KEY marker.

  3. Convert the serverkey.pem file into a PKCS#12 file (a file with a .pfx extension). "PKCS" refers to a group of public key cryptography standards devised and published by RSA Security. PKCS#12 defines a file format commonly used to store private keys with accompanying public key certificates, protected with a password-based symmetric key.

    There are various tools you can use to convert the serverkey.pem file into a PKCS#12 file. One of them is the openssl tool. Here is the command to convert the file using openss1:

          openssl pkcs12  -export  -in serverkey.pem -out s1as.pfx

    In response, you will be prompted for the export password. Enter a password such as "changeit" or the GlassFish master password.

    The s1as.pfx file will now contain the required signed server certificate and the private key.

  4. Delete the original s1as self-signed entry, if it exists, by issuing the following command:

          certutil -D -n s1as -d $AS_NSS_DB

  5. Use the pk12util utility to import the new s1as.pfx file into the NSS store by issuing the following command:

          pk12util -i s1as.pfx -d $AS_NSS_DB 

    pk12util is an NSS utility available inside the GlassFish installation template directory for the Enterprise Profile. The utility is used to import or export a PCKS#12 file to and from an NSS store.

    In response to the command, you will be prompted for the passwords for the NSS soft token and PKCS#12 file. Supply the appropriate passwords. You should then see the following message indicating that the import was successful:

          pk12util: PKCS12 IMPORT SUCCESSFUL   

There are two other cases to consider:

  • The application server profile is the enterprise profile and the server key pair is already in a PKCS#12 file. If there is already an entry in the store with alias s1as, all you have to do is perform step 4 as described in "When the Enterprise Profile is Used" to delete the original entry:

         certutil -D -n s1as -d $AS_NSS_DB 

    Then perform step 5 to import the new s1as.pfx file into the NSS store:

          pk12util -i s1as.pfx -d $AS_NSS_DB 

    If there is no entry in the store with alias s1as, simply perform step 5.

  • The application server profile is the developer profile and the server key pair is already in a PKCS#12 file. In this case, all you need to do is perform step 5 as described in When the Enterprise Profile is Used to delete the original s1as entry. Then use the pkcs12import utility to import the PCKS#12 file into the GlassFish keystore:

         pkcs12import.sh -file s1as.pfx -alias s1as 
         -keystore keystore.jks -storepass changeit 
         -pass <exp_password>

    where <exp_password> is the password that was used when the PKCS#12 file was exported, for example, changeit.

    You can find the pkcs12import utility in the pkcs12import package, which you can download from the XWSS downloads page in Project Metro

For More Information

To learn more about SSL with GlassFish see SSL and CRL Checking with GlassFish v2.

Also see the following resources:


About the Author

Kumar Jayanti is a staff engineer at Sun Microsystems and works in the Web Technologies and Standards team. In his current role, Kumar is the lead for the XML and Web Services Security implementation and has also recently taken over responsibility for the GlassFish security module. He has been involved with the web services security effort at Sun since early 2004. Kumar holds an M.Tech degree in Computer Science from IIT Mumbai, India. His areas of interest include distributed computing, CORBA, XML, web services, and security.

Comments:

The Java Code to replace the original self-signed cert seems to ignore the possibility of a Cert-Chain being present in the Issued Cert. The modified code below might solve that issue.
--------------------------------------------
import java.io.\*;
import java.security.Key;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Collection;

public class Main {

public static void main(String[] args) throws Exception {
//args[] error checking logic omitted
//file containing signed cert reply from CA
String csrReplyFromCA = args[0];
//Path to GlassFish keystore.jks
String keystoreLocation = args[1];
//Password for GlassFish keystore.jks
String keystorePassword = args[2];
//The keyalias to be replaced : s1as in our example
String selfSignedKeyEntry = args[3];

//create the signed Cert
//Certificate cert = null;
Collection<? extends Certificate> certs = null;
FileInputStream fis =
new FileInputStream(csrReplyFromCA);
CertificateFactory cf =
CertificateFactory.getInstance("X.509");
//cert = cf.generateCertificate(fis);
certs = cf.generateCertificates(fis);
//now replace the original entry
char[] passwordChars =
keystorePassword.toCharArray();
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(new FileInputStream(keystoreLocation),
passwordChars);
Key key = keystore.getKey(selfSignedKeyEntry,
passwordChars);
Certificate[] certchain = certs.toArray(new Certificate[0]);
keystore.setKeyEntry(selfSignedKeyEntry, key,
//passwordChars, (new Certificate[]{cert}));
passwordChars,certchain);
keystore.store(new FileOutputStream(
keystoreLocation), passwordChars);
}
}
---------------------------------------

Posted by Kumar Jayanti on January 15, 2008 at 03:20 PM PST #

Great article. Thanks!

GlassFish has multiple profiles. The default ones are the ones that you mention.

Posted by Kedar Mhaswade on March 20, 2008 at 11:38 PM PDT #

I'm having some problems with the pkcs12import utility. It doesn't seem to be able to find my keystore file. See the trace below (running form the domain config directory):

#: ./pkcs12import.sh -file <CA file> -alias s1as -keystore keystore.jks
does not existt location keystore.jks

Any ideas?

Posted by JoeG on July 25, 2008 at 12:29 AM PDT #

Can you please run it as follows and see if it helps :

java -classpath <location of >/pkcs12import.jar com.sun.xml.wss.tools.PKCS12Import -file <CA file> -alias s1as -keystore keystore.jks

Thanks

Posted by kumar jayanti on July 27, 2008 at 05:03 PM PDT #

That seems to have done the trick. Thanks

Posted by JoeG on July 30, 2008 at 07:57 PM PDT #

The first step should be "Make a backup copy of keystore.jks before doing anything." After following all the steps under the Developer Profile, attempting to restart Glassfish resulted in a nasty:

java.security.UnrecoverableKeyExceptionCannot recover key

No clue what that means, but all of the steps I followed completed successfully with no warnings or errors. We have a local CA here that we trust, maybe it didn't like our local CA signing the cert?

Posted by Jason on September 23, 2008 at 11:04 PM PDT #

For, java.security.UnrecoverableKeyExceptionCannot recover key

Can you send me the complete stack trace.

Yes backing up the original keystore.jks is definitely a good idea.

But did you change the keystore password by any chance to be different from the GF master password ?.

Posted by kumar on October 06, 2008 at 03:12 AM PDT #

Well, I bought a Thawte certificate recently to suport payment on my site and I would say that this article really helped me.

But, keytool -import -v -alias s1as -file s1as.cert
-keystore keystore.jks -storepass <store_passwd>
is probably not the right command... I would suggest using

keytool -import -trustcacerts -alias s1as -keystore keystore.jks -file s1as.cert

Which in my case was the only one working...

Posted by Stéphane on October 27, 2008 at 03:09 AM PDT #

yes the option -trustcacerts is required. Thanks for the correction.

Posted by guest on February 10, 2009 at 03:35 PM PST #

I followed the developer version.
Stop the application server.
Commands worked. Keytool commands
described in
Restarted the server.

Guess SSL cert did not load at all.

Repeated several times same result.

What is going wrong ???

Posted by Greg Robinson on July 23, 2009 at 10:52 PM PDT #

Great article !!!

It was a big support for my GF-configuration!

Regards.

JessGP.

Posted by JessGP on September 29, 2010 at 10:50 PM PDT #

[exec] [ERROR] HTTPS hostname wrong: should be server name

i have created a versign test certificate with the domain name, unable to run wsgen to generate client artifacts.

Posted by hus on October 31, 2010 at 10:39 PM PDT #

Post a Comment:
Comments are closed for this entry.
About

edort

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today