Articles
Java Platform, Standard Edition
|
|
| By Carol Zhang and Phua Choon Hong, September 1, 2005 |
|
With the growing need for information security in today's digital systems, SSL has become the universally accepted method for setting up authenticated and encrypted communication between clients and servers. This article will discuss how to use the Sun Java System Application Server 8.1 software (hereafter referred to as Application Server) to build SSL-enabled web applications and how to implement SSL client authentication in the Java 2 Platform, Enterprise Edition (J2EE) 1.4 security realm.
In the TCP/IP protocol stack, SSL protocol sits between TCP/IP and the higher application-level protocols such as HTTP or SMTP. SSL implementation calls TCP/IP on behalf of the application, and it allows the SSL-enabled server and the SSL-enabled client to authenticate to each other and establish the encrypted connection between the two endpoints. This article addresses three fundamental concerns about SSL-based communication over the Internet:
SSL server authentication allows a user to confirm a server's identity. SSL-enabled client software can use standard techniques of public-key cryptography to check that a server's certificate and public ID are valid and have been issued by a certificate authority (CA) listed in the client's list of trusted CAs. This confirmation might be important if the user, for example, will be sending a credit card number over the network and wants to check the receiving server's identity.
SSL client authentication allows a server to confirm a user's identity. Using the same techniques as those for server authentication, an SSL-enabled server can check that a client's certificate and public ID are valid and have been issued by a CA in the server's list of trusted CAs. This confirmation might be important if the server, for example, is a bank that will be sending confidential financial information to a customer and wants to check the recipient's identity.
An encrypted SSL connection requires all information sent between a client and a server to be encrypted by the sending software and decrypted by the receiving software, thus providing a high degree of confidentiality. Confidentiality is important for both parties in any private transaction. In addition, all data sent over an encrypted SSL connection is protected with a mechanism to detect tampering -- that is, to determine automatically whether the data has been altered in transit.
The execution of the SSL protocol will go through several phases: the SSL handshake, the server authentication, and the optional client authentication phase. Only then is the encrypted communication channel established. This article will not detail the SSL protocol but will guide you in building an SSL-enabled web application in the Application Server.
Version 8.1 of the Application Server is the latest J2EE 1.4-compatible release of the Sun Java System Application Server. It consists of three editions: the Platform Edition for free download, a full J2EE 1.4 server with integrated web service security and JavaServer Faces technology; the Standard Edition, featuring remote, secure, multimachine management; and the Enterprise Edition, for the most demanding operational environments, incorporating the Standard Edition's capabilities.
To enable SSL, we will first learn how to manage certificate files, which store the digital certificates for all SSL participants including the server, the client, and the CA. The SSL engine will retrieve these digital certificates from the store and use them for authenticating and encrypting messages based on Public-Key Infrastructure (PKI) technology.
It's worth noting that the tools used for managing certificate files are different in the Application Server's three editions. The Platform Edition uses the Java Secure Socket Extension (JSSE) format and leverages the key tools shipped with the JDK for key-certificate management. The Standard Edition and Enterprise Edition, however, use Network Security Services (NSS) tools for storage and management. This article will use the tools in the Standard Edition as an example to depict a more typical scenario.
Note: JSSE is a set of Java packages that enable secure Internet communications. It implements a Java technology version of SSL and Transport Layer Security (TLS) protocols. It includes functionality for data encryption, server authentication, message integrity, and optional client authentication. By comparison, NSS provides a complete open source implementation of the crypto libraries used by Netscape, Sun, and other companies in a variety of products, including the Application Server. This article covers only the NSS tools for the Standard Edition and Enterprise Edition.
Before continuing, let's review some of this article's directory variable conventions:
as_install_dir refers to the directory in which the Application Server is installed. Default to /opt/sun/appserver. domain_dir refers to the directory in which the domain is installed. Default to /var/opt/appserver/domains.By default, the Application Server stores the certificate information in two NSS-format files in the domain_dir /domain_name/config directory:
key3.db by default, this file contains the Application Server's digital certificate, including its private key.cert8.db by default, this file contains the Application Server's trusted certificates, including public keys for other entities. Trusted certificates generally include those of CAs.The Certutil tool is used to set up and work with NSS digital certificates. This certificate database tool is a command-line utility that can create and modify the NSS-format files of cert8.db (Trust-store) and key3.db (KeyStore) database files. It can also list, generate, modify, or delete certificates within the cert8.db file, create or change the password, generate new public and private key pairs, display the contents of the key database, or delete key pairs within the key3.db file.
To verify the default-generated KeyStore and Trust-store files, use the following command to list the entries in the certificate files:
-bash- 3.00#
as_install_dir/lib/certutil -L -d
domain_dir/domain1/config
|
The following message will be printed out with the default installation of the Application Server:
verisignc1g1 T,c,c verisignc1g2 T,c,c ... ... s1as u,u,u |
The text on the output's left is the certificate's unique nickname, and the text on the right is a set of three capability identifiers for the CA, SSL, email and object signing, in that order. The most commonly used identifiers are the following:
p Valid peer P Trusted peer (implies p) c Valid CA T Trusted CA to issue client certs (implies c) C Trusted CA to issue server certs (for ssl only) (implies c) u User cert |
Note that the installation of the Application Server generates a digital certificate in NSS format, s1as, that is suitable for internal testing. We will talk about this in the next section and see how this sample digital certificate helps the internal testing. For production purposes, you may wish to add this certificate to the KeyStore and Trust-store files. Make sure to choose the correct certificate identifier for the newly added certificate. We will illustrate how to use the Certutil tool to manage the files.
In this part, we will make a simple configuration in the Admin Console to enable SSL for your server by using the preconfigured server certificate.
After the application server startup, bring your browser up to the Admin Console. Go to Configurations - > server-config -> HTTP Service -> HTTP Listeners. Click New to create a new HTTP listener with security enabled. The new listener is named HTTP-listener-3, and the listener port is set to 8282. Type the network address and select the virtual server name. The diagram illustrates the listener's configuration.
Access https:// server_name.domain_name:port_number/index.html in another browser. For example, if you use Mozilla in the Admin Console, then use Internet Explorer to access this page. Another option is to restart your browser to clear the SSL status. The Security Alert window will open and ask you whether to accept the certificate. If you accept, the Welcome page shows up. In the simple try, if you attempt to view the SSL detail in the Security Alert window, the s1as server certificate will be displayed.
We will now add more functions. After this section, we will learn how to deal with certificates in the real application.
You create a CA by using the Certutil tool. Following is the command to create the self-signed CA certificate and add it into the Application Server's certificate database:
-bash-3.00# certutil -S -x -1 -2 -5 -m 100 -t "TCu,Cu,Cu" -s \
"cn=testCA,o=Sun,ou=sun.com, C=CN" -n SSLTestCA -v 6 -d \
domain_dir/domain1/config
|
After issuing the command, you are required to type randomly on the keyboard until the progress meter is full to create the random seed for key creation. After the key is created, you are prompted to select from the following Options menu:
0 - Digital Signature 1 - Non-repudiation 2 - Key encipherment 3 - Data encipherment 4 - Key agreement 5 - Cert signing key 6 - CRL signing key Other to finish |
One by one, select options 0, 1, 5, 6 and 9, and type y when the program asks whether this is a critical extension. After that, you will be prompted to select from other option menus, where you should choose 5, 6, 9 for SSL CA and S/MIME CA.
Once you complete this command, you will find that SSLTestCA CTu,Cu,Cu are listed in the entries of the certificate files.
In a production environment, you are more likely to import the existing CA certificate to the certificate database than to generate your own keys in self-signed form. For example, to import the certificate from a file named rootCA.cer, you would execute this command:
-bash-3.00#
as_install_dir/lib/certutil -A -n rootCA -t "TCu,Cu,Tuw" -i \
rootCA.cer -d
domain_dir/domain1/config
|
Create and add the server certificate, which is signed by the newly created CA, SSLTestCA:
-bash-3.00#
as_install_dir
|
In the Admin Console, go to Configurations -> server-config -> HTTP Service -> HTTP Listeners. Select HTTP-listener-3, which you configured in the previous step. Check Enable Client Certificate; type MyServerCert as the certificate nickname; and enable SSL3, TLS, and Ciphers Suites. Save your configurations. This will enable the client certification for the HTTP listener.
Execute the following command to generate the client certificate:
-bash-3.00#
as_install_dir/lib/certutil -S -c SSLTestCA -m 160 -t \
"Pu,Pu,Pu" -s "cn=carol, ou=sun.com, C=CN" -n ClientCert -v 12 -d \
domain_dir/domain1/config
|
Export the client certificate to a file:
-bash-3.00#
as_install_dir/lib/pk12util -o ClientCert.p12 -n ClientCert -d \
domain_dir/domain1/config
|
In each of the above steps, you will be prompted for the master password to the certificate database. Enter the master password with which you configured the Application Server.
Open your browser and import ClientCert.p12 to your certificate store. Optionally, you can import the CA's certificate to your browser to avoid the Security Alert window. Please refer to Mozilla help or Microsoft IE help for instructions on how to import a certificate.
In the previous section, we discussed how to configure SSL in the Application Server by setting up the encrypted channel for the message transfer in the transportation level. How does the J2EE application, which runs above the transportation level, make use of the client credentials to do the application-level authentication? We will reveal the implementation details in this section.
There are two types of J2EE security implementations: container authentication and custom authentication. We will review the concepts of the two authentication implementations and examine how SSL fits into the two schemes.
A container is an environment in which an application runs. Container authentication is the process of telling the container the identity of the user making the current request. The J2EE specification defines four mechanisms to authenticate users: HTTP basic authentication, HTTP digest authentication, HTTPS client authentication, and HTTP form-based authentication.
Version 8.1 of the Application Server supports three types of authentication:
In both of these methods, you have the option of enabling the encryption of user credentials by using SSL.
As we have seen, the user credentials passed between client and server are different in the three authentication methods, that is, where SSL technology plays different roles.
We will focus on the SSL client authentication implementation, in which the public-key certificate is used as a user credential. Generally speaking, security in the J2EE application can be enforced by using either a declarative approach or a programmatic approach. When using the declarative approach, the application developer defines an application's security constraints outside the application code. These declaratives are made in deployment descriptors ( web.xml: ejb-jar.xml), and container runtime environments guarantee their enforcement.
To configure SSL client authentication, you define roles in the J2EE deployment descriptor file, web.xml, and the corresponding role mappings between the client certificate Distinguish Name (DN) and roles in the Application Server deployment descriptor file, sun-application.xml (or sun-web.xml for individually deployed web modules).
Here is the code in web.xml:
<security-constraint>
<web-resource-collection>
<web-resource-name>clientcert security test</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>staffmember</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>certification</realm-name>
</login-config>
|
The sample deployment contains the following security configuration:
/* (the url-pattern).staffmember role can access these resources (the role-name).Client-Cert authentication method.Here is the code in sun-application.xml:
<security-role-mapping>
<role-name>staffmember</role-name>
<principal-name>cn=carol, ou=sun.com, C=CN</principal-name>
<group-name>staff</group-name>
</security-role-mapping>
|
The declared principal name and group name belong to the role staffmember. The principal name is the certificate DN, which uniquely identifies the client.
Download the source code ClientCertApp.ear. Then cut and paste the principal name that you used in your configuration into sun-application.xml. Deploy this application and access the page https:// server_name.domain_name:port_number/<web-context-root>/index.jsp .
As we discussed earlier, the client certification-based container authentication in the Application Server provides only rudimentary principal- and role-based authentication. When you want more flexibility for the authentication, you may find custom authentication a better choice.
The most common implementation of custom authentication is that user credentials are retrieved from a form submission and then compared against a persistent store, usually a database or LDAP. The user is either allowed or denied access to the system. If the user is allowed access, an object is usually placed into the session that identifies the user who has access to the application. After that, the business logic related to authorization can be implemented and enforced based on the established user identity and predefined rules.
You can place this example code into an authentication servlet filter:
User user = (User) request.getSession.getAttribute("com.test.User");
If (user == null) {
X509Certificate ax509certificate[] =
(X509Certificate[])request.getAttribute
("javax.servlet.request.X509Certificate");
String userDN = ax509certificate[0].getSubjectDN().toString();
user = CustomAuthentication.login(userDN);
if (user != null && user.isValid()) {
request.getSession().setAttribute("com.test.User", user);
}
}
|
The code above allows the application to check the session for the User object on subsequent requests to determine whether a user has logged in and has access to the application.
The following code is an example of an implementation of the CustomAuthentication object used in the servlet code above. In addition, this implementation uses JDBC to verify the user's credentials with a relational database.
import ...
public class CustomAuthenticator {
public static final String SQL = "select * from user where userDN = ?";
public static User login(String userDN)
throws AuthenticationException {
User user = null;
Connection connection = getConnection();
PreparedStatement statement = null;
ResultSet rs = null;
try {
statement = connection.prepareStatement(SQL);
statement.setString(0, userDN);
rs = statement.executeQuery();
if (rs.next()) {
user = new User(userDN);
}
}
catch (SQLException e) {
closeObjects(connection, statement, rs);
throw new AuthenticationException("Unable to verify user");
}
return user;
}
...
}
|
You can download a simple file, GetCert.zip, that demonstrates how to retrieve the client certification from an HTTP request.
Another solution implements the standard Java Authentication and Authorization Service (JAAS) interfaces. Such implementations call the custom authenticator shown above rather than calling a container authenticator. The code snippet above could easily be placed in a JAAS login module instead of in a servlet to accomplish this type of custom authentication.
As many people know, using SSL can slow the application's performance significantly because encrypting and decrypting messages are CPU-intensive operations. The common solution is to leverage some dedicated hardware -- the SSL accelerator or its equivalents -- to do the SSL-related computing. This device sits between the client browser and the web server, establishes the SSL connection with the client, and does inbound and outbound message encryption and decryption. But note that the SSL connection is terminated at the SSL accelerator end and that the protocol between the SSL accelerator and the web server is HTTP.
However, if the client certificate is required as the user credential to access the web application, we need to check whether the SSL accelerator has the capability to provide the client certificate or the client DN to the back-end web server in the HTTP request.
SSL is widely used as the security schema in web applications. However, despite its popularity, it has some limitations.
First, SSL is designed to provide point-to-point security, which falls short for some scenarios in which multiple intermediary nodes may exist between the two endpoints while end-to-end security is needed. For example, in a typical web services environment, in which XML-based business documents route through multiple intermediary nodes, those intermediary nodes can have difficulty participating in security operations in an integrated fashion.
Second, SSL secures communication at the transport level rather than at the application or message level. As a result, messages are protected only in transmission over the network, but sensitive data used in the application or stored on the user's hard disk is not generally protected if that system lacks an additional encryption technology.
Due to these limitations, SSL may not be suitable in every situation. Other technologies are being developed at the application level to address specific security concerns. For example, XML-based security schema have been developed in recent years to provide comprehensive and unified security schemas for web services.
SSL is a popular security technology, offering mutual authentication and message encryption in server-client communications. This article provides the steps to enable SSL in your web application and to implement SSL-enabled J2EE security in Application Server 8.1. The article also discusses SSL's limitations to help developers better position SSL technology.
I am indebted to the following people for their help with this article:
Carol Zhang is a member of the technical staff in the Market Development Engineering department at Sun. With seven years of experience in software development and technical consulting, Carol provides technical consultation to Sun's partner software vendors in China.
Phua Choon Hong is a member of the technical staff in Remote Software Delivery, supporting Sun's customers in application server issues.