While creating the 3.3 version of my SSL HOWTO, I also polished off the wording here and there and added a TOC and section marks for easier navigation. Attached are both the 3.3 and 4.0 versions of the file. Consider this 4.0 version to supercede the one I sent last night (or early this morning, as it were :-) If someone could please let me know for sure that adding extension JARs to the "{JDK_HOME}/jre/lib/ext" directory under JDK 1.1.8 effectively makes them "installed extensions" (makes them available without necessarily being in the CLASSPATH) just like in >= JDK 1.2. Other than that, I'm pretty sure the TC 3.3 version of the doc is valid for JDK 1.1.8 environments as well. If someone a little more familiar with 1.1.8 could maybe give it a quick once-over and see if anything jumps out, that would be great. - Christopher
Tomcat 4.0 Standalone - SSL Configuration Author: Christopher Cain <[EMAIL PROTECTED]> Contents =================================== Section 1: QUICKSTART INSTRUCTIONS Instructions Section 2: SSL PRIMER & TIPS Introduction to SSL SSL and Tomcat Certificates General Tips on Running SSL Section 3: CONFIGURATION Configuration Instructions Known Issues Troubleshooting --------------------- Section 1: Quickstart Instructions ---------------------- INSTRUCTIONS 1. Download JSSE 1.0.2 or later and make it an "installed extension" by copying the JAR files into "$JAVA_HOME/jre/lib/ext". 2. Create the certificate keystore (passwords: "changeit") keytool -genkey -alias tomcat -keyalg RSA 3. Add the "com.sun.net.ssl.internal.ssl.Provider" provider to the java.security file. 4. Uncomment the secure connector example in server.xml and tweak as necessary ----------------------- Section 2: SSL Primer and Tips ------------------------ INTRODUCTION TO SSL SSL, or Secure Sockets Layer, is a technology which allows web browsers and web servers to communicate over a secured connection. This means that the data being sent is encrypted by one side, transmitted, then decrypted by the other side prior to any processing. This is a two-way process, meaning that both the server AND the browser encrypt all traffic before sending out data. Another aspect of the SSL protocol is Authentication. The means that 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 "Certificate", in an attempt to prove to you that the site you are accessing is what you think it is. This particular functionality may or may not be important to you, depending on your circumstances. See the CERTIFICATES topic for more information. In certain cases, the server may also request a certificate from your web browser, asking for proof that YOU are who you claim to be. This is known as "Client Authentication", although in practice this is a somewhat rare and highly specialized configuration. Most SSL-enabled web servers do not request Client Authentication, although Tomcat does support it. SSL AND TOMCAT It is important to note that configuring Tomcat to take advantage of secure sockets is usually only necessary when running it as a standalone web server. When running Tomcat primarily as a Servlet/JSP engine behind another web server, such as Apache or Microsoft IIS, it is usually necessary to configure the primary web server to handle the SSL connections. Typically, this server will negotiate all SSL-related functionality, then pass on any requests destined for the Tomcat engine only after decrypting those requests. In this environment, Tomcat does not know, nor does it care, that communications between the primary web server and the client are taking place over a secure connection. It transmits and receives data just as it normally would. CERTIFICATES In order to implement SSL, a web server must have an associated certificate for each external interface (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. While a broader explanation of certificates is beyond the scope of this document, think of a certificate as a digital "driver's license" for an internet address. It states what company the address is associated with, along with some basic contact information about the site owner or administrator. This "driver's license" is cryptographically signed by its owner, and an "official" certificate is therefore extremely difficult for anyone else to forge. For sites involved in e-commerce, or any other business in which Authentication of identity is important, an "official" certificate is typically purchased from a well-known "Certificate Authority" (CA) such as VeriSign or Thawte. In many cases, however, Authentication is not a really a concern. An administrator may simply want to ensure that the data being transmitted and received by the server is private and cannot be snooped by anyone who may be eavesdropping on the connection. Fortunately, Sun provides a relatively simple command-line tool, called "keytool," which can easily create "Self-Signed" certificates. Self-signed certificates are simply user-generated certificates which have not been officially blessed by any well-known CA and are therefore not really guaranteed to be authenticate at all. Again, this may or may not even be important, depending on your specific requirements and needs. GENERAL TIPS ON RUNNING SSL The first time a user attempts to access a secured page on your site, he or she is typically presented with a dialog containing the details of the certificate, such as company and contact name, and asked if he or she wishes to accept the certificate as valid and continue with the transaction. Some browsers will provide an option for permanently accepting a given certificate as valid, in which case the user will not be bothered with the prompt each time they visit your site. Other browsers do not provide this option. Once approved by the user, a certificate will be considered valid for at least the entire browser session. Also, while the SSL protocol was designed to be as efficient as securely possible, encryption/decryption is a naturally expensive process from a performance standpoint. If is not strictly necessary to run an entire web application over SSL, and indeed a developer can pick and choose which pages require a secure connection and which do not For a reasonably busy site, it is customary to only run certain pages under SSL, namely those pages where sensitive information could possibly be exchanged. This would include things like login pages, personal information pages, and store checkouts, 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 of "http:". Any pages which absolutely REQUIRE a secure connection should check the protocol type associated with the page request and take the appropriate action if "https" was not specified. -------------------------- Section 3: Configuration --------------------------- CONFIGURATION INSTRUCTIONS (0) Download and Install JSSE 1.0.2 or Later Download the JSSE package, available at <http://java.sun.com/products/jsse/index-102.html>. If you built Tomcat from source, you have probably already downloaded this package. If you are running JDK 1.4 (currently in beta), these classes have been integrated directly into the JDK, so you may be able to skip this step. After expanding the package, copy all three JAR files (jcert.jar, jnet.jar, and jsse.jar) into your "$JAVA_HOME/jre/lib/ext" directory. This effectively makes them "installed extensions," and obviates the need to put them into the CLASSPATH. Note: DO NOT copy any of these JAR files into any of the internal Tomcat classloading repositories (i.e. $TC_HOME/common/lib, $TC_HOME/lib, and $TC_HOME/server/lib). If they are also in your CLASSPATH or installed extensions, this will cause Tomcat to fail on startup! (1) Prepare the Certificate Keystore Tomcat currently operates only on JKS format keystores. This is the Sun's standard "Java KeyStore" format, and this is the format created by Sun's "keytool" utility. "keytool" is a generic command-line utility for managing keystore, and is included in the JDK. * To import an existing certificate into a JKS keystore, please read the documentation on the keytool utility. * To create a new keystore from scratch, containing a single, self-signed certificate, execute the following from a terminal command-line: keytool -genkey -alias tomcat -keyalg RSA (The RSA algorithm should be preferred as a secure algorithm, and also to ensure general compatibility with other servers and components.) This command will create a new file, in the home directory of the user under which you run it, named ".keystore". To specify a different location/filename, add the "-keystore" parameter (you will need to specify the new path/name in the appropriate configuration file as explained later): keytool -genkey -alias tomcat -keyalg RSA -keystore /path/to/my/keystore After executing this command, you will first be prompted for the keystore password. The default password used by Tomcat is "changeit" (all lowercase), although you can specify a custom password if you like (you will need to specify the custom password in the appropriate configuration file as explained later). Next you will be prompted for general information about the certificate, such as company, contact name, etc. Finally, you will be prompted for the "key password", which is the password specifically for the certificate. You MUST specify the same password that was used as the keystore password (currently, as noted by the keytool prompt, hitting RETURN does this automatically). If everything was successful, you now have a keystore and certificate for your server. (2) Add the SSL provider to the JVM When the JVM attempts to load up the necessary classes for SSL during execution, it checks for an appropriate "Provider" for the service. In order to let the JVM know that it has a suitable SSL provider installed (which was actually included in the JSSE package), you must edit the "$JAVA_HOME/jre/lib/security/java.security" file and add an entry. The very first section of this configuration file should have one or more lines that resemble the following: security.provider.1=sun.security.provider.Sun The syntax here is: security.provider.{search order number}={installed provider class} In order to register the SSL provider, add a line like the following: security.provider.3=com.sun.net.ssl.internal.ssl.Provider The "3" is just an example number. Please use a number not already taken in the existing provider list. (3) Edit the "$TC_HOME/conf/server.xml" Configuration File The final step is to configure your secure socket in the "server.xml" configuration file. An example SSL <Connector> is included in the default "server.xml" file installed with Tomcat. There will be a comment just above it to the effect of: <!-- Define an SSL HTTP/1.1 Connector on port 8443 --> ... or something similar. The connector itself is commented-out by default, so all that remains is to remove the comment tags and customize as necessary. The primary attribute you may wish to change is the "port" attribute, which tells Tomcat which port to bind the secure socket to. If you change the port number here, you should also change the "redirectPort" attribute on any non-secure sockets you have defined, as that is how Tomcat redirects secure connection attempts sent to insecure HTTP ports. Finally, you will notice a <Factory> tag nested inside the secure <Connector> tag. This is where you will set the keystore location and/or password. If you chose to go with the defaults in both cases, you do not have to make any further changes, and you should now be ready to roll. If you specified a different location/filename for the keystore, add a "KeystoreFile" attribute and set the value to point to your keystore file. If you chose a password other than "changeit", add a "KeystorePass" attribute and set the value to your password. A custom keystore, therefore, might look like this: <Factory className="org.apache.catalina.net.SSLServerSocketFactory" clientAuth="false" protocol="TLS" KeystoreFile="/path/to/.keystore" KeystorePass="mypassword" /> (4) Fire Up That Bad Boy You should now be in business. When you start Tomcat, you should now see a new binding on the specified port number, listening for https requests. If not ... KNOWN ISSUES * It is not currently possible to use a keystore with multiple key/cert entries, as Tomcat will simply select the first entry. This issue is currently being resolved and will hopefully be remedied before the next release (Beta 8, if one is necessary, or the official 4.0 release). TROUBLESHOOTING * I get "java.security.NoSuchAlgorithmException ..." when I try to execute the "keytool" command or on Tomcat startup. The JVM cannot find the JSSE JARS, or the provider is not registered. Make sure that the "security.provider.3=com.sun.net.ssl.internal.ssl.Provider" line is in your "$JAVA_HOME/jre/lib/security/java.security" file, and that the three JSSE JARS are either in the "$JAVA_HOME/jre/lib/ext" directory (preferred) or in your CLASSPATH. * When I try to start Tomcat, I get a long stacktrace with "java.io.FileNotFoundException {some_directory}/{some file} not found" somewhere near the beginning. Tomcat cannot find the keystore. If you didn't specify a custom filename using "-keystore" keytool parameter (when generating the store), make sure that the "/.keystore" file is in the home directory of the user TOMCAT IS RUNNING AS. If you DID specify a custom file, make sure that the file exists, that Tomcat has at least read access to it, and that it is properly specified in the "KeystoreFile" attribute of the <Factory> tag in the "server.xml" file. * When I try to start Tomcat, I get a long stacktrace with "java.io.FileNotFoundException Keystore was tampered with, or password was incorrect" near the beginning. Assuming that someone hasn't _actually_ tampered with it, the most likely cause is that Tomcat is using the wrong password. If you specified the Tomcat default password of "changeit" (all lowercase), ensure that there is not a "KeystorePass" attribute on the secure <RequestInterceptor> tag, or if there is, that it is set to "changeit". If you specified a different password, ensure that the "KeystorePass" attribute IS present, and that it is correct. Passwords are case-sensitive.
Tomcat 3.3 Standalone - SSL Configuration Author: Christopher Cain <[EMAIL PROTECTED]> Contents =================================== Section 1: QUICKSTART INSTRUCTIONS Instructions Section 2: SSL PRIMER & TIPS Introduction to SSL SSL and Tomcat Certificates General Tips on Running SSL Section 3: CONFIGURATION Configuration Instructions Known Issues Troubleshooting --------------------- Section 1: Quickstart Instructions ---------------------- INSTRUCTIONS 1. Download JSSE 1.0.2 or later and make it an "installed extension" by copying the JAR files into "$JAVA_HOME/jre/lib/ext". 2. Create the certificate keystore (passwords: "changeit") keytool -genkey -alias tomcat -keyalg RSA 3. Add the "com.sun.net.ssl.internal.ssl.Provider" provider to the java.security file. 4. Uncomment the secure connector example in server.xml and tweak as necessary ----------------------- Section 2: SSL Primer and Tips ------------------------ INTRODUCTION TO SSL SSL, or Secure Sockets Layer, is a technology which allows web browsers and web servers to communicate over a secured connection. This means that the data being sent is encrypted by one side, transmitted, then decrypted by the other side prior to any processing. This is a two-way process, meaning that both the server AND the browser encrypt all traffic before sending out data. Another aspect of the SSL protocol is Authentication. The means that 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 "Certificate", in an attempt to prove to you that the site you are accessing is what you think it is. This particular functionality may or may not be important to you, depending on your circumstances. See the CERTIFICATES topic for more information. In certain cases, the server may also request a certificate from your web browser, asking for proof that YOU are who you claim to be. This is known as "Client Authentication", although in practice this is a somewhat rare and highly specialized configuration. Most SSL-enabled web servers do not request Client Authentication, although Tomcat does support it. SSL AND TOMCAT It is important to note that configuring Tomcat to take advantage of secure sockets is usually only necessary when running it as a standalone web server. When running Tomcat primarily as a Servlet/JSP engine behind another web server, such as Apache or Microsoft IIS, it is usually necessary to configure the primary web server to handle the SSL connections. Typically, this server will negotiate all SSL-related functionality, then pass on any requests destined for the Tomcat engine only after decrypting those requests. In this environment, Tomcat does not know, nor does it care, that communications between the primary web server and the client are taking place over a secure connection. It transmits and receives data just as it normally would. CERTIFICATES In order to implement SSL, a web server must have an associated certificate for each external interface (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. While a broader explanation of certificates is beyond the scope of this document, think of a certificate as a digital "driver's license" for an internet address. It states what company the address is associated with, along with some basic contact information about the site owner or administrator. This "driver's license" is cryptographically signed by its owner, and an "official" certificate is therefore extremely difficult for anyone else to forge. For sites involved in e-commerce, or any other business in which Authentication of identity is important, an "official" certificate is typically purchased from a well-known "Certificate Authority" (CA) such as VeriSign or Thawte. In many cases, however, Authentication is not a really a concern. An administrator may simply want to ensure that the data being transmitted and received by the server is private and cannot be snooped by anyone who may be eavesdropping on the connection. Fortunately, Sun provides a relatively simple command-line tool, called "keytool," which can easily create "Self-Signed" certificates. Self-signed certificates are simply user-generated certificates which have not been officially blessed by any well-known CA and are therefore not really guaranteed to be authenticate at all. Again, this may or may not even be important, depending on your specific requirements and needs. GENERAL TIPS ON RUNNING SSL The first time a user attempts to access a secured page on your site, he or she is typically presented with a dialog containing the details of the certificate, such as company and contact name, and asked if he or she wishes to accept the certificate as valid and continue with the transaction. Some browsers will provide an option for permanently accepting a given certificate as valid, in which case the user will not be bothered with the prompt each time they visit your site. Other browsers do not provide this option. Once approved by the user, a certificate will be considered valid for at least the entire browser session. Also, while the SSL protocol was designed to be as efficient as securely possible, encryption/decryption is a naturally expensive process from a performance standpoint. If is not strictly necessary to run an entire web application over SSL, and indeed a developer can pick and choose which pages require a secure connection and which do not For a reasonably busy site, it is customary to only run certain pages under SSL, namely those pages where sensitive information could possibly be exchanged. This would include things like login pages, personal information pages, and store checkouts, 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 of "http:". Any pages which absolutely REQUIRE a secure connection should check the protocol type associated with the page request and take the appropriate action if "https" was not specified. -------------------------- Section 3: Configuration --------------------------- CONFIGURATION INSTRUCTIONS (0) Download and Install JSSE 1.0.2 or Later Download the JSSE package, available at <http://java.sun.com/products/jsse/index-102.html>. If you built Tomcat from source, you may have already downloaded this package. If you are running JDK 1.4 (currently in beta), these classes have been integrated directly into the JDK, so you may be able to skip this step. After expanding the package, copy all three JAR files (jcert.jar, jnet.jar, and jsse.jar) into your "$JAVA_HOME/jre/lib/ext" directory. This effectively makes them "installed extensions," and obviates the need to put them into the CLASSPATH. Note: DO NOT copy any of these JAR files into any of the internal Tomcat classloading repositories (i.e. $TC_HOME/lib/*). If they are also in your CLASSPATH or installed extensions, Tomcat may fail on startup! (1) Prepare the Certificate Keystore Tomcat currently operates only on JKS format keystores. This is the Sun's standard "Java KeyStore" format, and this is the format created by Sun's "keytool" utility. "keytool" is a generic command-line utility for managing keystore, and is included in the JDK. * To import an existing certificate into a JKS keystore, please read the documentation on the keytool utility. * To create a new keystore from scratch, containing a single, self-signed certificate, execute the following from a terminal command-line: keytool -genkey -alias tomcat -keyalg RSA (The RSA algorithm should be preferred as a secure algorithm, and also to ensure general compatibility with other servers and components.) This command will create a new file, in the home directory of the user under which you run it, named ".keystore". To specify a different location/filename, add the "-keystore" parameter (you will need to specify the new path/name in the appropriate configuration file as explained later): keytool -genkey -alias tomcat -keyalg RSA -keystore /path/to/my/keystore After executing this command, you will first be prompted for the keystore password. The default password used by Tomcat is "changeit" (all lowercase), although you can specify a custom password if you like (you will need to specify the custom password in the appropriate configuration file as explained later). Next you will be prompted for general information about the certificate, such as company, contact name, etc. Finally, you will be prompted for the "key password", which is the password specifically for the certificate. You MUST specify the same password that was used as the keystore password (currently, as noted by the keytool prompt, hitting RETURN does this automatically). If everything was successful, you now have a keystore and certificate for your server. (2) Add the SSL provider to the JVM When the JVM attempts to load up the necessary classes for SSL during execution, it checks for an appropriate "Provider" for the service. In order to let the JVM know that it has a suitable SSL provider installed (which was actually included in the JSSE package), you must edit the "$JAVA_HOME/jre/lib/security/java.security" file and add an entry. The very first section of this configuration file should have one or more lines that resemble the following: security.provider.1=sun.security.provider.Sun The syntax here is: security.provider.{search order number}={installed provider class} In order to register the SSL provider, add a line like the following: security.provider.3=com.sun.net.ssl.internal.ssl.Provider The "3" is just an example number. Please use a number not already taken in the existing provider list. (3) Edit the "$TC_HOME/conf/server.xml" Configuration File The final step is to configure your secure socket in the "server.xml" configuration file. An example SSL <RequestInterceptor> is included in the default "server.xml" file installed with Tomcat. It should be the second connector listed, and it will have a "secure" attribute set to true. The connector itself is commented-out by default, so all that remains is to remove the comment tags and customize as necessary. The primary attribute you may wish to change is the "port" attribute, which tells Tomcat which port to bind the secure socket to. If the keystore file is anywhere other than a file named ".keystore" in the home directory of the user Tomcat runs as, you will need to add a "Keystore" attribute to the interceptor which points to the file, If the password is anything other than "changeit" (all lowercase), you will need to add a "Keypass" attribute with the correct password. An interceptor with a custom keystore, therefore, might look like this (note that attribute names and values are case-sensitive): <RequestInterceptor className="org.apache.tomcat.modules.server.Http10Interceptor" port="8443" secure="true" Keystore="/path/to/my.keystore" Keypass="mypassword" /> (4) Fire Up That Bad Boy You should now be in business. When you start Tomcat, you should now see a new binding on the specified port number, listening for https requests. If not ... KNOWN ISSUES * It is not currently possible to use a keystore with multiple key/cert entries, as Tomcat will simply select the first entry. This issue is currently being resolved and will hopefully be remedied before 3.3 Beta 2 is released. TROUBLESHOOTING * I get "java.security.NoSuchAlgorithmException ..." when I try to execute the "keytool" command or on Tomcat startup. The JVM cannot find the JSSE JARS, or the provider is not registered. Make sure that the "security.provider.3=com.sun.net.ssl.internal.ssl.Provider" line is in your "$JAVA_HOME/jre/lib/security/java.security" file, and that the three JSSE JARS are either in the "$JAVA_HOME/jre/lib/ext" directory (preferred) or in your CLASSPATH. * When I try to start Tomcat, I get a long stacktrace with "java.io.FileNotFoundException {some_directory}/{some file} not found" somewhere near the beginning. Tomcat cannot find the keystore. If you didn't specify a custom filename using "-keystore" keytool parameter (when generating the store), make sure that the "/.keystore" file is in the home directory of the user TOMCAT IS RUNNING AS. If you DID specify a custom file, make sure that the file exists, that Tomcat has at least read access to it, and that it is properly specified in the "Keystore" attribute of the secure <RequesetInterceptor> tag in the "server.xml" file. * When I try to start Tomcat, I get a long stacktrace with "java.io.FileNotFoundException Keystore was tampered with, or password was incorrect" near the beginning. Assuming that someone hasn't _actually_ tampered with it, the most likely cause is that Tomcat is using the wrong password. If you specified the Tomcat default password of "changeit" (all lowercase), ensure that there is not a "Keypass" attribute on the secure <RequestInterceptor> tag, or if there is, that it is set to "changeit". If you specified a different password, ensure that the "Keypass" attribute IS present, and that it is correct. Passwords are case-sensitive.