Establishing a Secure Connection Using SSL
Secure Socket Layer (SSL) technology is security that is implemented at the transport layer (see Transport-Layer Security, for more information about transport layer security). SSL allows web browsers and web servers to communicate over a secure connection. In this secure connection, the data that is being sent is encrypted before being sent and then is decrypted upon receipt and before processing. Both the browser and the server encrypt all traffic before sending any data. SSL addresses the following important security considerations.
- Authentication: During your initial attempt to communicate with a web server over a secure connection, that server will present your web browser with a set of credentials in the form of a server certificate. The purpose of the certificate is to verify that the site is who and what it claims to be. In some cases, the server may request a certificate that the client is who and what it claims to be (which is known as client authentication).
- Confidentiality: When data is being passed between the client and the server on a network, third parties can view and intercept this data. SSL responses are encrypted so that the data cannot be deciphered by the third party and the data remains confidential.
- Integrity: When data is being passed between the client and the server on a network, third parties can view and intercept this data. SSL helps guarantee that the data will not be modified in transit by that third party.
Installing and Configuring SSL Support
If you are using the Sun Java System Application Server, an SSL HTTPS connector is already enabled. For more information on configuring SSL for the Application Server, refer to its Administration Guide (see Further Information, for a link to this document.)
If you are using a different application server or web server, an SSL HTTPS connector may or may not be enabled. If you are using a server that needs its SSL connector to be configured, consult the documentation for that server.
As a general rule, to enable SSL for a server, you must address the following issues:
You can verify whether or not SSL is enabled by following the steps in Verifying SSL Support.
Specifying a Secure Connection in Your Application Deployment Descriptor
To specify a requirement that protected resources be received over a protected transport layer connection (SSL), specify a user data constraint in the application deployment descriptor. The following is an example of a
web.xml
application deployment descriptor that specifies that SSL be used:<security-constraint> <web-resource-collection> <web-resource-name>view dept data</web-resource-name> <url-pattern>/hr/employee/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>DEPT_ADMIN</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint>A user data constraint (
<user-data-constraint>
in the deployment descriptor) requires that all constrained URL patterns and HTTP methods specified in the security constraint are received over a protected transport layer connection such as HTTPS (HTTP over SSL). A user data constraint specifies a transport guarantee (<transport-guarantee>
in the deployment descriptor). The choices for transport guarantee includeCONFIDENTIAL
,INTEGRAL
, orNONE
. If you specifyCONFIDENTIAL
orINTEGRAL
as a security constraint, that type of security constraint applies to all requests that match the URL patterns in the web resource collection and not just to the login dialog box.The strength of the required protection is defined by the value of the transport guarantee.
- Specify
CONFIDENTIAL
when the application requires that data be transmitted so as to prevent other entities from observing the contents of the transmission.- Specify
INTEGRAL
when the application requires that the data be sent between client and server in such a way that it cannot be changed in transit.- Specify
NONE
to indicate that the container must accept the constrained requests on any connection, including an unprotected one.The user data constraint is handy to use in conjunction with basic and form-based user authentication. When the login authentication methods set to
BASIC
orFORM
, passwords are not protected, meaning that passwords sent between a client and a server on an unprotected session can be viewed and intercepted by third parties. Using a user data constraint in conjunction with the user authentication mechanism can alleviate this concern. Configuring a user authentication mechanism is described in Specifying an Authentication Mechanism (page 957).Verifying SSL Support
For testing purposes, and to verify that SSL support has been correctly installed, load the default introduction page with a URL that connects to the port defined in the server deployment descriptor:
The
https
in this URL indicates that the browser should be using the SSL protocol. Thelocalhost
in this example assumes that you are running the example on your local machine as part of the development process. The8181
in this example is the secure port that was specified where the SSL connector was created. If you are using a different server or port, modify this value accordingly.The first time a user loads this application, the New Site Certificate or Security Alert dialog box displays. Select Next to move through the series of dialog boxes, and select Finish when you reach the last dialog box. The certificates will display only the first time. When you accept the certificates, subsequent hits to this site assume that you still trust the content.
Tips on Running SSL
The SSL protocol is designed to be as efficient as securely possible. However, encryption and decryption are computationally expensive processes from a performance standpoint. It is not strictly necessary to run an entire web application over SSL, and it is customary for a developer to decide which pages require a secure connection and which do not. Pages that might require a secure connection include login pages, personal information pages, shopping cart checkouts, or any pages where credit card information could possibly be transmitted. Any page within an application can be requested over a secure socket by simply prefixing the address with
https:
instead ofhttp:
. Any pages that absolutely require a secure connection should check the protocol type associated with the page request and take the appropriate action ifhttps
is not specified.Using name-based virtual hosts on a secured connection can be problematic. This is a design limitation of the SSL protocol itself. The SSL handshake, where the client browser accepts the server certificate, must occur before the HTTP request is accessed. As a result, the request information containing the virtual host name cannot be determined before authentication, and it is therefore not possible to assign multiple certificates to a single IP address. If all virtual hosts on a single IP address need to authenticate against the same certificate, the addition of multiple virtual hosts should not interfere with normal SSL operations on the server. Be aware, however, that most client browsers will compare the server's domain name against the domain name listed in the certificate, if any (this is applicable primarily to official, CA-signed certificates). If the domain names do not match, these browsers will display a warning to the client. In general, only address-based virtual hosts are commonly used with SSL in a production environment.
Working with Digital Certificates
Note: Digital certificates for the Application Server have already been generated and can be found in the directory
<
JAVAEE_HOME
>/domains/domain1/config/
. These digital certificates are self-signed and are intended for use in a development environment; they are not intended for production purposes. For production purposes, generate your own certificates and have them signed by a CA.Note: The instructions in this section apply to the PE version of the Application Server. In the EE version of the Application Server, the
certutil
utility is used to create digital certificates. If you are working with the EE version of the Application Server, refer to the EE version of the Administration Guide, a link to which is included in Further Information.
To use SSL, an application or web server must have an associated certificate for each external interface, or IP address, that accepts secure connections. The theory behind this design is that a server should provide some kind of reasonable assurance that its owner is who you think it is, particularly before receiving any sensitive information. It may be useful to think of a certificate as a "digital driver's license" for an Internet address. It states with which company the site is associated, along with some basic contact information about the site owner or administrator.
The digital certificate is cryptographically signed by its owner and is difficult for anyone else to forge. For sites involved in e-commerce or in any other business transaction in which authentication of identity is important, a certificate can be purchased from a well-known certificate authority (CA) such as VeriSign or Thawte. If your server certificate is self-signed, you must install it in the Application Server's keystore file (
keystore.jks
). If your client certificate is self-signed, you should install it in the Application Server's truststore file (cacerts.jks
).Sometimes authentication is not really a concern--for example, an administrator may simply want to ensure that data being transmitted and received by the server is private and cannot be snooped by anyone eavesdropping on the connection. In such cases, you can save the time and expense involved in obtaining a CA certificate and simply use a self-signed certificate.
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. This property is fundamental to establishing trust and privacy in transactions. For example, using SSL, the server computes a value and encrypts the value using its private key. The encrypted value is called a digital signature. The client decrypts the encrypted value using the server's public key and compares the value to its own computed value. If the two values match, the client can trust that the signature is authentic, because only the private key could have been used to produce such a signature.
Digital certificates are used with the HTTPS protocol to authenticate web clients. The HTTPS service of most web servers will not run unless a digital certificate has been installed. Use the procedure outlined later to set up a digital certificate that can be used by your application or web server to enable SSL.
One tool that can be used to set up a digital certificate is
keytool
, a key and certificate management utility that ships with the Java SE SDK. It enables users to administer their own public/private key pairs and associated certificates for use in self-authentication (where the user authenticates himself or herself to other users or services) or data integrity and authentication services, using digital signatures. It also allows users to cache the public keys (in the form of certificates) of their communicating peers. For a better understanding ofkeytool
and public key cryptography, read thekeytool
documentation at the following URL:Creating a Server Certificate
A server certificate has already been created for the Application Server. The certificate can be found in the
<
JAVAEE_HOME
>/domains/domain1/config/
directory. The server certificate is inkeystore.jks
. Thecacerts.jks
file contains all the trusted certificates, including client certificates.If necessary, you can use
keytool
to generate certificates. Thekeytool
stores the keys and certificates in a file termed a keystore, a repository of certificates used for identifying a client or a server. Typically, a keystore contains one client or one server's identity. The default keystore implementation implements the keystore as a file. It protects private keys by using a password.If you don't specify a directory when specifying the keystore file name, the keystores are created in the directory from which the
keytool
command is run. This can be the directory where the application resides, or it can be a directory common to many applications.To create a server certificate follow these steps:
Run
keytool
to generate the server keystore, which we will namekeystore.jks
. This step uses the aliasserver-alias
to generate a new public/private key pair and wrap the public key into a self-signed certificate insidekeystore.jks
. The key pair is generated using an algorithm of type RSA, with a default password ofchangeit
. For more information onkeytool
options, see its online help athttp://java.sun.com/j2se/1.5.0/docs/tooldocs/solaris/keytool.html
.
Note: RSA is public-key encryption technology developed by RSA Data Security, Inc. The acronym stands for Rivest, Shamir, and Adelman, the inventors of the technology.
From the directory in which you want to create the keystore, run
keytool
with the following parameters.
Note: You must enter the server name in response to
keytool's
first prompt, in which it asks for first and last names. For testing purposes, this can belocalhost
.The host specified in the keystore must match the host identified in the
host
variable specified in the<
INSTALL
>/javaeetutorial5/examples/common/build.properties
file when running the example applications.
- Export the generated server certificate in
keystore.jks
into the fileserver.cer
.
<
JAVA_HOME
>\bin\keytool -export -alias server-alias
-storepass changeit -file server.cer -keystore keystore.jks- If you want to have the certificate signed by a CA, read Signing Digital Certificates for more information.
- To create the trust-store file
cacerts.jks
and add the server certificate to the trust-store, runkeytool
from the directory where you created the keystore and server certificate. Use the following parameters:
<
JAVA_HOME
>\bin\keytool -import -v -trustcacerts
-alias server-alias -file server.cer
-keystore cacerts.jks -keypass changeit
-storepass changeitInformation on the certificate, such as that shown next, will display.
<
INSTALL
>/javaeetutorial5/examples/gs 60% keytool -import
-v -trustcacerts -alias server-alias -file server.cer
-keystore cacerts.jks -keypass changeit -storepass changeit
Owner: CN=localhost, OU=Sun Micro, O=Docs, L=Santa Clara, ST=CA, C=US
Issuer: CN=localhost, OU=Sun Micro, O=Docs, L=Santa Clara, ST=CA, C=US
Serial number: 3e932169
Valid from: Tue Apr 08
Certificate fingerprints:
MD5: 52:9F:49:68:ED:78:6F:39:87:F3:98:B3:6A:6B:0F:90
SHA1: EE:2E:2A:A6:9E:03:9A:3A:1C:17:4A:28:5E:97:20:78:3F:
Trust this certificate? [no]:- Enter
yes
, and then press theEnter
orReturn
key. The following information displays:
Certificate was added to keystore
[Saving cacerts.jks]Signing Digital Certificates
After you've created a digital certificate, you will want to have it signed by its owner. After the digital certificate has been cryptographically signed by its owner, it is difficult for anyone else to forge. For sites involved in e-commerce or any other business transaction in which authentication of identity is important, a certificate can be purchased from a well-known certificate authority such as VeriSign or Thawte.
As mentioned earlier, if authentication is not really a concern, you can save the time and expense involved in obtaining a CA certificate and simply use the self-signed certificate.
Obtaining a Digitally-Signed Certificate
This example assumes that the keystore is named
keystore.jks
, the certificate file isserver.cer
, and the CA file iscacerts.jks
. To get your certificate digitally signed by a CA:
- Generate a Certificate Signing Request (CSR).
keytool -certreq -alias server-alias -keyalg RSA
-file <csr_filename
> -keystore cacerts.jks
- Send the contents of the
csr_filename
for signing.- If you are using Verisign CA, go to
http://digitalid.verisign.com/
. Verisign will send the signed certificate in e-mail. Store this certificate in a file.Using a Different Server Certificate with the Application Server
Follow the steps in Creating a Server Certificate, to create your own server certificate, have it signed by a CA, and import the certificate into
keystore.jks
.Make sure that when you create the certificate, you follow these rules:
- When you create the server certificate,
keytool
prompts you to enter your first and last name. In response to this prompt, you must enter the name of your server. For testing purposes, this can belocalhost
.- The server/host specified in the keystore must match the host identified in the
host
variable specified in the<
INSTALL
>/javaeetutorial5/examples/common/build.properties
file for running the example applications.- Your key/certificate password in
keystore.jks
should match the password of your keystore,keystore.jks
. This is a bug. If there is a mismatch, the Java SDK cannot read the certificate and you get a "tampered" message.- If you want to replace the existing
keystore.jks
, you must either change your keystore's password to the default password (changeit
) or change the default password to your keystore's password.To specify that the Application Server should use the new keystore for authentication and authorization decisions, you must set the JVM options for the Application Server so that they recognize the new keystore. To use a different keystore than the one provided for development purposes, follow these steps.
- Start the Application Server if you haven't already done so. Information on starting the Application Server can be found in Starting and Stopping the Application Server (page 28).
- Start the Admin Console. Information on starting the Admin Console can be found in Starting the Admin Console (page 29).
- Select Application Server in the Admin Console tree.
- Select the JVM Settings tab.
- Select the JVM Options tab.
- Change the following JVM options so that they point to the location and name of the new keystore. There current settings are shown below:
-Djavax.net.ssl.keyStore=${com.sun.aas.instanceRoot}/config/keystore.jks
-Djavax.net.ssl.trustStore=${com.sun.aas.instanceRoot}/config/cacerts.jks- If you've changed the keystore password from its default value, you need to add the password option as well:
-Djavax.net.ssl.keyStorePassword=
your_new_password
- Logout of the Admin Console and restart the Application Server.
Miscellaneous Commands for Certificates
To check the contents of a keystore that contains a certificate with an alias
server-alias
, use this command:
keytool -list -keystore keystore.jks -alias server-alias -v
To check the contents of the
cacerts
file, use this command:
keytool -list -keystore cacerts.jks
Enabling Mutual Authentication over SSL
This section discusses setting up client-side authentication. When both server-side and client-side authentication are enabled, it is called mutual, or two-way, authentication. In client authentication, clients are required to submit certificates that are issued by a certificate authority that you choose to accept.
There are at least two ways to enable mutual authentication over SSL:
- PREFERRED: Set the method of authentication in the
web.xml
application deployment descriptor toCLIENT-CERT
. This enforces mutual authentication by modifying the deployment descriptor of the given application. By enabling client authentication in this way, client authentication is enabled only for a specific resource controlled by the security constraint, and the check is only performed when the application requires client authentication.RARELY: Set the
clientAuth
property in thecertificate
realm totrue
if you want the SSL stack to require a valid certificate chain from the client before accepting a connection. Afalse
value (which is the default) will not require a certificate chain unless the client requests a resource protected by a security constraint that usesCLIENT-CERT
authentication. When you enable client authentication by setting theclientAuth
property to "true"
, client authentication will be required for all the requests going through the specified SSL port. If you turnclientAuth
on, it is on all of the time, which can be a tremendous performance hit.When client authentication is enabled in both of these ways, client authentication will be performed twice.
Creating a Client Certificate for Mutual Authentication
If you have a certificate signed by a trusted Certificate Authority (CA) such as Verisign, and the Application Server's
cacerts.jks
file already contains a certificate verified by that CA, you do not need to complete this step. You only need to install your certificate in the Application Server's certificate file when your certificate is self-signed.From the directory where you want to create the client certificate, run
keytool
as outlined here. When you press Enter,keytool
prompts you to enter the server name, organizational unit, organization, locality, state, and country code.You must enter the server name in response to
keytool
's first prompt, in which it asks for first and last names. For testing purposes, this can belocalhost
. The host specified in the keystore must match the host identified in thejavee.server.host
variable specified in your<
INSTALL
>/javaeetutorial5/examples/bp-project/build.properties
file. If this example is to verify mutual authentication and you receive a runtime error stating that the HTTPS host name is wrong, re-create the client certificate, being sure to use the same host name that you will use when running the example. For example, if your machine name isduke
, then enterduke
as the certificate CN or when prompted for first and last names. When accessing the application, enter a URL that points to the same location--for example,https://duke:8181/mutualauth/hello
. This is necessary because during SSL handshake, the server verifies the client certificate by comparing the certificate name and the host name from which it originates.To create a keystore named
client-keystore.jks
that contains a client certificate namedclient.cer
, follow these steps:
Note: It is dangerous to put client certificates in the
cacerts.jks
file. Any certificate you add to thecacerts
file effectively means it can be a trusted root for any and all certificate chains. After you have completed development, delete the development version of thecacerts
file and replace it with the original copy.
- Generate the client certificate. Enter the following command from the directory where you want to generate the client certificate:
<
JAVA_HOME
>\bin\keytool -genkey -alias client-alias -keyalg RSA -keypass changeit
-storepass changeit -keystore client_keystore.jks- Export the generated client certificate into the file
client.cer
.
<
JAVA_HOME
>\bin\keytool -export -alias client-alias
-storepass changeit -file client.cer -keystore client_keystore.jks- Add the certificate to the trust-store file
<
JAVAEE_HOME
>/domains/domain1/config/cacerts.jks
. Runkeytool
from the directory where you created the keystore and client certificate. Use the following parameters:
<
JAVA_HOME
>\bin\keytool -import -v -trustcacerts
-alias client-alias -file client.cer
-keystore <JAVAEE_HOME
>/domains/domain1/config/cacerts.jks
-keypass changeit -storepass changeitThe
keytool
utility returns this message:
Owner: CN=Java EE Client, OU=Java Web Services, O=Sun, L=Santa Clara, ST=CA, C=US
Issuer: CN=Java EE Client, OU=Java Web Services, O=Sun, L=Santa Clara, ST=CA, C=US
Serial number: 3e39e66a
Valid from: Thu Jan 30 18:58:50 PST 2005 until: Wed Apr 30
19:58:50 PDT 2005
Certificate fingerprints:
MD5: 5A:B0:4C:88:4E:F8:EF:E9:E5:8B:53:BD:D0:AA:8E:5A
SHA1:90:00:36:5B:E0:A7:A2:BD:67:DB:EA:37:B9:61:3E:26:B3:89:46:
32
Trust this certificate? [no]: yes
Certificate was added to keystore- Restart the Application Server.