|< Free Open Study >|| |
Commercial web sites make extensive use of Secure Socket Layer (SSL), which has emerged as the standard security mechanism on the Web. It provides a secure connection between the client and the server.
SSL is an international standard, in the form of an IETF RFC called Transport Layer Security (TLS) 1.0 - accessible at http://www.ietf.org/rfc/rfc2246.txt.
You're probably familiar with the way SSL works on your browser - look for the "secure indicator" (typically a small padlock) when you visit a secure site. Once we have made a successful SSL connection we can be sure that:
We have reached a legitimate website
The data sent between our browser and the server will be encrypted
In order to understand how to configure SSL for servlet containers we need to understand how SSL works, and how it relates to public key encryption. An SSL connection provides three guarantees:
The authenticity of the server
The privacy of data transferred via encryption
The integrity of the data when it is transferred (the data must not be modified during transfer between client and server)
The third guarantee provides protection against a "man in the middle" security attack, in which the message is intercepted between the client and the server.SSL provides this authentication, privacy, and integrity using a combination of public key encryption and shared secret encryption.
Encryption is the act of transforming a message (via some mathematical algorithm) into an unintelligible form. Typically the encryption transformation is performed using a sequence of numeric values or a key, which is also used in the decryption process. Possession of the key enables the recipient to decode the message. This sort of encryption is frequently referred to as shared secret encryption as each party shares a common key.
SSL uses this simple form of encryption to encode the stream of data between the client and the server. Anyone who learns the shared key will be able to access the transmitted data, but both the client and the server need to know the key. Consequently, SSL depends on a considerably stronger form of encryption during its handshaking phase (prior to the creation of the shared secret session), in order to establish a secured session between a client and a server - public key encryption
Unlike shared secret encryption, public key encryption uses two keys that differ in value. The keys are generated using a mathematical algorithm in which anything encrypted with one of the keys can only be decrypted with the other. Such keys are known as asymmetric keys. What makes public key encryption so strong is that having one of the keys in the key pair will not allow you to work out the other (at least not without trying different sequences for a very long time.)
Having generated two keys with such a special property, we can then designate one of them as a public key, and the other one as a private key. The private key is never shared with anyone else. Compromising the private key will leave your data unsecured. The public key on the other hand, can be widely circulated, so that any client who wishes to communicate with the server can use it.
During an encrypted communications session between the server and the client:
The server can encrypt all the data going to the client using its private key
The client can then use the public key to decrypt the data
Going the other way:
The client can use the server's public key to encrypt the data
The server can use its private key to decrypt it
Since the public key is the only key in the world that can decrypt data encrypted by the server's private key the client can be assured that it is indeed talking to the server (as only the server possesses the private key).
This all sounds elegant and straightforward, but unfortunately there is a problem. Public key encryption requires tremendous processing power to encrypt and decrypt the data. For this reason SSL uses the faster and simpler shared secret encryption for encrypting its data stream. Public key encryption is used only to exchange the key that is to be used for shared secret encryption.
SSL utilizes public key encryption during its handshaking process (when a client wants to establish a secured session with a server). After that, SSL enters into a communication session in which shared secret encryption is used to encrypt the data.
The following occurs during the SSL handshaking phase:
The server is authenticated
The client and server agree on a set of encryption algorithms to use
Optionally, the client can also be authenticated (although this is not done in the usual client to web server connection)
The client and server negotiate a shared secret key, which is used to encrypt the data during the second communications phase of the protocol
The key negotiated between the client and the server is only valid for a single session.
In the next few sections we'll take a closer look at how the first step of the handshaking phase - server authentication - is accomplished in SSL.
Public key encryption requires the wide distribution of the public key. This is more difficult than it first appears. Imagine the hundreds of sites that you may visit through an SSL connection. If we were to use public key encryption directly, we would need to have possession of a site's public key before we can establish a session with that site. Storing and managing so many public keys would become a problem; particularly when a site changes its key pair.
One solution would be to have the server send its public key immediately upon connection, but this would mean that we have a server handing a client its own public key, and the client will be using this public key to assert the server's identity, opening up a large security loophole.
While we may not trust a server handing out a public key that it claims as its own, we can collectively trust groups such as VeriSign (http://www.verisign.com) or Thawte (http://www.thawte.com/). These are Certification Authorities (CA), and they provide a mechanism by which we can validate a server's public key as it is handed to you.
This mechanism makes use of transitive trust. First, we must assume that we have obtained the public key of the CA, obtained through some highly secured means (built right into modern browsers). Now we only need to have faith in the CA's public key because they will in turn vouch for the authenticity of a server's public key. This is done through a digital certificate (cert).
A cert is an unencrypted message that contains a server's public key as well as other information such as domain name, IP, name of issuing CA, and expiration date, together with a digital signature that is obtained from a CA. The CA will take the server's information and authenticate it via some external means (for example, human intervention), and will then vouch for the authenticity of that information by signing it with its own private key. This signing is done using a digital signature.
A digital signature is appended at the end of a message, and is used to ensure the integrity of the message during transmission. In this case, the message plus the signature forms the certificate. A digital signature is computed by putting the content of the message through the one-way hash algorithm (MD5) that produces a message digest. MD5 is a frequently used algorithm, details of which can be found at http://www.ietf.org/rfc/rfc1321.txt. The digest is then encrypted using the private key of the CA and appended to the message.
When it receives a certificate supplied by the server, a client can ascertain the validity of the information on the certificate by performing the same one-way hash on the content; decrypting the signature using the CA's well-known public key; and finally comparing the two hash values. In this way, the authenticity of the server is established through the transitive trust relationship between the client, CA, and the server:
One of the most frequently used formats for certificates is based on the X.509 format, described at http://www.ietf.org/rfc/rfc2459.txt. Tomcat's SSL implementation supports the use of this standard format.
During SSL server authentication, a client checks the identity of the server to make sure that it is contacting the genuine server. After the connection of a client via unencrypted sockets, the server sends a cert to the client. The client then performs a series of checks to authenticate the server, including:
Verifying that the certificate hasn't expired
Verifying that the CA issuing the certificate is to be trusted
Verifying the domain name against the one on the certificate
Validating the CA's digital signature on the certificate (by decrypting the signature with the CA's public key and comparing it against the message digest), in order to ensure that the certificate is issued by the CA and the information has not been tampered with
After server authentication is performed, the client and server will check the set of cryptographic algorithms available to them and negotiate a cipher suite that represents the algorithms that are available to both of them. Finally, a key is generated (using one of the shared secret encryption algorithms from the cipher suite) and shared between the client and server for the communication phase of the protocol.
There are at least two ways that one can set up an SSL-enabled web site based on Tomcat 4 (and most other servlet containers/application servers). Using a web server front end and using a standalone configuration.
When we use a web server front end, we use a connector between the web server and Tomcat. The establishment of the SSL connection, and encryption and decryption of the data stream, all occur between the client and the web server. The connection between the web server and Tomcat 4 is via a physically secured network and the data is not encrypted when transferred:
The exact configuration of the systems in this scenario is specific to the web server. The documentation of all the leading web servers such as Apache, IIS, and iPlanet provide details of setting up an SSL server, so we won't cover them here.
We can also use a standalone configuration in which Tomcat is used as both the web server (for serving static content), and the application server. In this case, the SSL connection is established between a client's browser and Tomcat 4 directly:
Instead of re-implementing the complex SSL layer, Tomcat makes use of the Java Secure Socket Extension (JSSE) standard extension that is available from http://java.sun.com/products/jsse/ (JSSE comes as an integral part of J2SE 1.4). JSSE provides a pure Java implementation of SSL, implemented as a set of custom socket factory classes that enable any non-SSL application to easily use by simply specifying one of the factory classes when creating a socket.
JSSE consists of a set of JAR files: jsse.jar, jcert.jar, and jnet.jar. While Tomcat 4 can use an environment variable named JSSE_HOME for locating these extensions, the most reliable way is to install JSSE as a standard extension by copying these JAR files to the %JAVA_HOME%\jre\lib\ext directory or to make them available to Tomcat by copying them to the %CATALINA_HOME%\common\lib.
JSSE obtains public key and cert information from a keystore. The keystore used by JSSE is in a proprietary format called Java Key Store (JKS). Users can create a keystore, generate public key pairs, and create certificates using a tool that is part of the standard JDK: keytool, which has several options:
Generates a public and private key pair, and creates a self-signed cert
Exports a cert in binary or text format
Specifies a text alias that can be use to retrieve the keys after creation
Lists the content of the store
Specifies a key generation algorithm (RSA is usually used)
Specifies the path to the keystore
Specifies the password for the keystore
Lists the number of days that the cert will be valid for
Self-signed certificates represent a cert vouching for our authenticity, whose signing CA is ourselves. While not useful in production environments, they are useful for testing as obtaining custom certs can be expensive.
To create a keystore that we can use on Tomcat, we can use the following command:
keytool -genkey -alias wrox -keystore .\keystore -keyalg RSA -validity 365
When we execute this command, keytool will prompt for some additional information. Answer them according to the following screenshot (blank entries indicate that we do not need to enter any value and can simply press the return key):
The fields for the cert are standard X.509 required fields. As we are creating a cert for our server, it is important to use the server's name when prompted - in our case localhost. We also need to be careful to set the same password for the keystore and for the cert entry (here we set it to abc123). This is because Tomcat only allows us to specify a single password for both.
There may be a significant delay during the generation of the public key pair and the creation a self-signed cert, after which there will be a file named keystore in your working directory. We can see the content of the keystore by running this command:
keytool -keystore .\keystore -list
You will be prompted for the keystore password. The tool will then list the content of the keystore (in this case it only contains the self-signed cert we just created).
We need to move this keystore to a location where Tomcat can locate it. Create a keystore directory underneath %CATALINA_HOME% and copy the keystore file to it.
Next, we need to get our browser to recognize us as a CA. This can be done by exporting our cert and then importing it into the browser we are using. The command to export a cert using keytool is:
keytool -export -keystore .\keystore -alias wrox -rfc -file wrox.cer
The tool will prompt for our password, and then generate a key file in RFC 1421, Base64 encoded format (which is easily transportable). The key file is stored as wrox.key in our working directory and will look something like this:
-----BEGIN CERTIFICATE----- MIICQDCCAakCBDwLYykwDQYJKoZIhvcNAQEEBQAwZzELMAkGA1UEBhMCVUsxEDAOBgNVBAgTB1Vu a25vd24xEDAOBgNVBAcTB1Vua25vd24xEzARBgNVBAoTCldyb3ggUHJlc3MxCzAJBgNVBAsTAklU MRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMDExMjAzMTEzNDAxWhcNMDIxMjAzMTEzNDAxWjBnMQsw CQYDVQQGEwJVSzEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjETMBEGA1UEChMK V3JveCBQcmVzczELMAkGA1UECxMCSVQxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEA59pRG46XWhV7syzNeZqPv00NDSHYRO9zK0xWnxe3SNHUSNRhrVbRJ89y E5jWmjXz4fZtE1W9DADN6NBgQVyYmbcu68hqeqmzsM4bGxYVMRNCkIFtkawgYBD9CKSgKdDGvean nugTSiHBF6xRfkUy4wUbLo0ECZ4utZQHFYcYCTMCAwEAATANBgkqhkiG9w0BAQQFAAOBgQAuQ66L EXaCrNTI8jyw9TcOZsKS3+LWJN0nAnitURfSkejgzmOYkLYdwCagvU3eLPPe7BCOndqiYZQmuSod o8C+wBaCyLYcg3BqBuOs/RLxUooNA5EpU5W2rhJotW9vkiEGPhRCjZGuM+jvAc3zIsVJCQFqrqK0 aaphYb5gre8t7g== -----END CERTIFICATE-----
We will import this as a CA to Internet Explorer (to import to other browsers you should consult their documentation). Select Internet Options under the Tools menu. Click on the Content tab and you should see something similar to the following:
Click the Certificates… button, and then the Trusted Root Certification Authorities tab. You should see a list of already installed CAs:
Click the Import… button, and walk through the wizard, importing our wrox.cer file. The wizard will recognize the certificate format and install it into the Root Certificate Store.
Finally, we can configure Tomcat to take advantage of the server side SSL setup. This can be done by editing server.xml:
<Connector className="org.apache.catalina.connector.http.HttpConnector" port="8443" minProcessors="5" maxProcessors="75" enableLookups="true" acceptCount="10" debug="0" scheme="https" secure="true"> <Factory className="org.apache.catalina.net.SSLServerSocketFactory" keystoreFile="keystore/keystore" keystorePass="abc123" clientAuth="false" protocol="TLS"/> </Connector>
Within the <Service name="Tomcat-Standalone"> element, you should find an entry already in place. All we need to do is to uncomment it and add the keystoreFile and keystorePass attributes. The <Factory> element instructs Tomcat on where to access the public key and certs required for the SSL session (as implemented by the JSSE socket factory classes).
Remember that the JSSE JAR files will need to be available to Tomcat for this to work. Using the browser that you have added the CA cert to, navigate to https://localhost:8443/. You should now get the SSL-enabled Tomcat home page (note the padlock icon in the lower right hand corner):
Non-SSL access is still available via port 8080. The portion of an application that does not need a secure connection should avoid using SSL access as it is considerably more processor-intensive that non-SSL access.
It's worth taking a moment to examine what's happening here. The browser authenticates the server by:
Receiving a certificate from Tomcat (localhost)
Validating the certificate against a trusted CA
Checking the hostname used to access the resource (localhost)
Checking the expiration date of the certificate (a year from now)
All of the above checks must be successful before a shared secret key is generated and used communication. If we try to access https://localhost:8443/index.html using a browser that hasn't had our certificate installed, we'll see a warning. For example, the following dialog is presented by Netscape 6.2:
|< Free Open Study >|| |