This is an overview of how to use Jetty with JSSE as an SSL implementation. The 1.0 release of JSSE contains both a frame work for third party providers and a reference implementation. These instructions detail how to use the reference implementation and have been tested against keys generated from the sun keytool utility and 024 and 2048 bit RSA keys from openssl
Note that while Jetty2 compiles and runs under Java 1.1.x, SSL and JSSE support require at least Java 1.2.x.
There are three steps.
This document also contains an environment description with version numbers and a list of outstanding issues.
Sun Key/Certificate Pair
In order to generate the certificate with the reference implementation
you need to install the JSEE as a security provider for JDK. You can do
this by editing $JDK12/jre/lib/security/java.security and adding the
following lines:
security.provider.2=com.sun.net.ssl.internal.ssl.ProviderThis is assuming that JSSE is the only additional provider you want installed. Note that all Jetty Jsse classes manually install this provider as needed, so it may be worthwhile removing this line after the certificate has been generated, as it can interfer with other providers (see loading OpenSSL keypair below).
The certificate can be generated and loaded with the keytool utility with a command like:
keytool -genkey -keyalg RSA -storepass testpasswd -keypass testpasswd
OpenSSL Key/Certificate Pair
The procedure to get a key and certificate for use with OpenSSL
is described in Thawte's Apache SSL Key and CSR Generation Instructions.
Here is a log of me following a simplified version of those instructions.
$ mkdir keytest $ cd keytest $ openssl genrsa -des3 -rand /var/log/wtmp:/var/log/boot.log:/var/tmp/lastlog:/var/log/messages 1024 > bee.hive.net.key 235890 semi-random bytes loaded Generating RSA private key, 1024 bit long modulus ...............................++++++ ...............................................++++++ e is 65537 (0x10001) Enter PEM pass phrase: Verifying password - Enter PEM pass phrase: $ openssl req -new -key bee.hive.net.key > bee.hive.net.csr Using configuration from /usr/share/ssl/openssl.cnf Enter PEM pass phrase: You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]: State or Province Name (full name) [Some-State]: Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []:bee.hive.net Email Address []:postmaster@bee.hive.net Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:challenge An optional company name []: $ cat bee.hive.net.csr -----BEGIN CERTIFICATE REQUEST----- MIIB3zCCAUgCAQAwgYQxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRl MSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFTATBgNVBAMTDGJl ZS5oaXZlLm5ldDEmMCQGCSqGSIb3DQEJARYXcG9zdG1hc3RlckBiZWUuaGl2ZS5u ZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKE3ChwybfDMtDBm54mWKpHQ wQ5Dla0JC4SSlP4xhq6J2j5MpXWM1CgpqJWwYqr4tEFrD0kMOUZDby6R5nC3iuSt bIlWx6xztzKI6Jngg8wM2FRwlMbZIfUvmgJ6abvknE0VRSEm4RRCQehnk7FCz1aa W8esCm9r+9vXvULhGXAhAgMBAAGgGjAYBgkqhkiG9w0BCQcxCxMJY2hhbGxlbmdl MA0GCSqGSIb3DQEBBAUAA4GBAHtvSlMrKaiP5Yfn/WgbaLUbEXlf/9DX2EIWVI4p QTpHApt/DQLdYNXs2stzXNOfZNGtmhATvvfOOLTZYxqn3l/qYeiAJMDU2q2yc7YU i3yvGO2HVbRlB2vbtdFG6CzzaA/nszi+ZXQ07ltOUX7B0WMZLyHt/lUFMH3Rc7qF CRw2 -----END CERTIFICATE REQUEST-----
Use a browser to paste the above into the a form for submission to the CA. I used Thawte's Test Certificate CA. Place the result into a suitably named file as follows:
$ cat > bee.hive.net.crt -----BEGIN CERTIFICATE----- MIICqjCCAhOgAwIBAgIDPLWSMA0GCSqGSIb3DQEBBAUAMIGHMQswCQYDVQQGEwJa QTEiMCAGA1UECBMZRk9SIFRFU1RJTkcgUFVSUE9TRVMgT05MWTEdMBsGA1UEChMU VGhhd3RlIENlcnRpZmljYXRpb24xFzAVBgNVBAsTDlRFU1QgVEVTVCBURVNUMRww GgYDVQQDExNUaGF3dGUgVGVzdCBDQSBSb290MB4XDTAwMDgxMjEwMzYxMloXDTAx MDgxMjEwMzYxMlowgYQxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRl MSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFTATBgNVBAMTDGJl ZS5oaXZlLm5ldDEmMCQGCSqGSIb3DQEJARYXcG9zdG1hc3RlckBiZWUuaGl2ZS5u ZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKE3ChwybfDMtDBm54mWKpHQ wQ5Dla0JC4SSlP4xhq6J2j5MpXWM1CgpqJWwYqr4tEFrD0kMOUZDby6R5nC3iuSt bIlWx6xztzKI6Jngg8wM2FRwlMbZIfUvmgJ6abvknE0VRSEm4RRCQehnk7FCz1aa W8esCm9r+9vXvULhGXAhAgMBAAGjJTAjMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwG A1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEEBQADgYEAhSvgL8nliB29TcOFakQ2i5kq VMwVaxWSFBv2oyxW4/p1/7IMUYBTjIDx0wurkbY9I+iJ2rVfLKYtqmU/94oRQnkB FrTXTweQPhJSdjvSaZj3QAQBwca6gYcy3mrGCiOHHe/rkN+Yo0FnDyutqmsqs7oB eHL4df28CBXV6tva77g= -----END CERTIFICATE-----
During this step you will be doing a few exposed things from a security point of view, so only do this in a secure directory on a secure machine. Remember to clean up properly.
The JSSE provider is not able to handle openSSL key pairs, so another provider is required. Get your hands on a copy of the Bouncy Castle Crypto Package from The Legion of the Bouncy Castle. Other JCE 1.2 providers may work too but at the moment this is the one that this is tested against. You will only need it for the key loading stage so install it on your safe machine somewhere.
Firstly you will need to decrypt the private key. Do this using openssl like this:
$ openssl rsa -in bee.hive.net.key -out bee.hive.net.clearkey -outform DER read RSA key Enter PEM pass phrase: writing RSA keyIf this fails, check that the sun security provider is not registered in the java.security file. It only needs to be registered their if you are generating your keys with sun's keytool. Jetty registers the provider on an as need be basis.
Next, load the key and the cert into a JKS keystore. The class com.mortbay.Util.KeyPairTool is used to load the keys into the keystore. It has the following arguments:
-key FILENAME, location of private key [MANDATORY] -cert FILENAME, location of certificate [MANDATORY] -storepass PASSWORD, keystore password [OPTIONAL - RISKY] -keypass PASSWORD, password for new entry [=STOREPASS - RISKY] -keystore FILENAME, location of keystore, [~/.keystore] -storetype STRING, name/type of keystore, [jks] -alias NAME, alias used to store key [mykey] -provider NAME, name of provider class [org.bouncycastle.jce.provider.BouncyCastleProvider]If passwords are not provided on the command line, they are prompted for. While they still appear on the screen, this is a much safer option as they do not get saved in shell histories or process listings.
$ /bin/sh $ java com.mortbay.Util.KeyPairTool -key bee.hive.net.clearkey -cert bee.hive.net.crt -storepass testpasswd -keystore mykeystore Loaded the private key... Loaded the public key... Will create keystore: keypair.keystore Keys have been written to keystore
Remember to clean up! a simple way to do this without going to overboard is:
$ man man > bee.hive.net.clearkey $ cat /var/log/messages | compress > bee.hive.net.clearkey $ man ls > bee.hive.net.clearkey $ rm bee.hive.net.clearkey
You now have a keystore with your keypair stashed away in it. If you ignored the previous step, you also have your private key in the clear in your file system - SO CLEAN UP! This is your last warning.
You can use the jdk-1.2 keytool to manipulate the key/cert now that it is in there. You can use it to change the password for instance.
$ keytool -storepasswd Enter keystore password: testpasswd New keystore password: newpasswd Re-enter new keystore password: newpasswd keytool -list Enter keystore password: newpasswd Keystore type: jks Keystore provider: SUN Your keystore contains 1 entry: mykey, Sat Aug 12 21:11:19 GMT+10:00 2000, keyEntry, Certificate fingerprint (MD5): 1A:DA:C0:35:F0:A3:EC:AD:AB:D8:5F:48:78:A0:CB:90 $
Assuming you already have a functioning Jetty2 Server:
Add the SunJsseListener alongside the HttpListeners, e.g. you could change lines that look like:
main.LISTENER.all.CLASS : com.mortbay.HTTP.HttpListener main.LISTENER.all.ADDRS : 0.0.0.0:8080;127.0.0.1:8888To:
main.LISTENER.http.CLASS : com.mortbay.HTTP.HttpListener main.LISTENER.http.ADDRS : 0.0.0.0:8080;127.0.0.1:8888 main.LISTENER.https.CLASS : com.mortbay.HTTP.SunJsseListener main.LISTENER.https.ADDRS : 0.0.0.0:8443
Remember that the default port for https is 443 not 80, so change 80 to 443 if you want to be able to use URL's without explicit port numbers. For a production site it normally makes sense to have a HttpListener on port 80 and a SunJsseListener on port 443.
Choose a private directory with restricted access to keep your keystore in. even though it has a password on it, the password is configured into the runtime environment so is vulnerable to theft.
Change the way you start Jetty to:
java -Djetty.ssl.password=testpasswd \ -Djetty.ssl.keystore=/home/jetty2/keystore \ com.mortbay.Jetty.DemoRemember that putting your password on the command line is a security risk. If you leave it out, you will be prompted for it.
You may then access the SSL port with a URL like: https://yourhost:8443/Dump If you get an javax.net.ssl.SSLException, check that you have remembered the s in https.
The following issues are outstanding:
The environment this procedure was developed in was: