At my company we have an online portal where the content is published from an java application over an ssl connection. For several years the online portal used SSL certificates from Verisign, however, this year in order to save some $$$ we decided to switch all of our certificates to Go Daddy. It took a few additional steps this year to make the java publishing application trust the SSL certificate from the online portal
A little background on Java and certificates.
Java manages certificates in 2 groups:
- Root certificates and code signing certificates
- Individual site certificates
Root certificates and code signing certificates are stored in the cacerts file that is a part of the jre. Typically this is in:
- $JAVA_HOME/jre/lib/security/cacerts for Unix/Linux or
- %JAVA_HOME%/jre/lib/security/cacerts for Windows
Individual site certificates are typically stored in a “truststore” that you create and maintain.
When you start your java program you reference the truststore using the appropriate Java -D options
- “-Djavax.net.ssl.trustStore=”
- “-Djavax.net.ssl.trustStorePassword=”
All groups of certificates are managed by the java keytool program.
Unlike Web Browsers and their automatic SSL certificate acceptance of certificates signed by trusted entities, a certificate must be registered with java before it will be trusted. To do this you manually enroll the site’s public ssl certificate into the “truststore” and any missing root/signing certificates into the JVM’s cacerts file.
Updating the cacerts
Currently, Go Gaddy has 2 valid Certificate chains; “ValCert Legacy Certificate Chain” and “New Go Daddy Certificate Chain”. Our new certificate used the “New Go Daddy Certificate Chain”. I downloaded the “Go Daddy Class 2 Certification Authority Root Certificate — DER Format” and the “Go Daddy Secure Server Certifcate (Intermediate Certificate)” from the site https://certs.godaddy.com/Repository.go. I installed these into my cacerts file
This is my script to update the cacerts
#!/bin/sh TOD=`date +%y%m%d_%H%M%S` JAVA_HOME=/usr/java/jdk1.5.0_11 CACERT_STORE=${JAVA_HOME}/jre/lib/security/cacerts CERT_FILE1=gd-class2-root.cer CERT_ALIAS1=godaddyclass2ca CERT_FILE2=gd_intermediate.crt CERT_ALIAS2=godaddy-intermediate-cert cp ${CACERT_STORE} ${CACERT_STORE}_${TOD} if [ -f ${CACERT_STORE}_${TOD} ] keytool -import -trustcacerts -keystore ${CACERT_STORE} -file ${CERT_FILE1} -alias ${CERT_ALIAS1} keytool -import -trustcacerts -keystore ${CACERT_STORE} -file ${CERT_FILE2} -alias ${CERT_ALIAS2} fi |
You will be prompted to enter the password of the cacerts file. If you have not changed it, then it will be “changeit”
Updating your truststore
Now you are ready to enroll the public SSL certificate. In my case, the site was an IIS site and I used the Windows certificate export and picked format DER. Do not export your private key! I then downloaded the certificate to the system where the Java code was going to run and enrolled it using a script similar to the one below
#!/bin/sh TOD=`date +%y%m%d_%H%M%S` JAVA_HOME=/usr/java/jdk1.5.0_11 HOST=www.yoursite.com CERT=www.yoursite.com_export_DER_x509.cer KEYSTORE=mytruststore cp ${KEYSTORE} ${KEYSTORE}_${TOD} if [ -f ${KEYSTORE}_${TOD} ]; then $JAVA_HOME/bin/keytool -delete -keystore ${KEYSTORE} -alias ${HOST} $JAVA_HOME/bin/keytool -import -keystore ${KEYSTORE} -alias ${HOST} -file ${CERT} fi |
You will be prompted to enter the password of the “mytruststore” file. This is the value that you set when you created the truststore
To use your truststore when you run your java program
I add the ssl -D options to my JAVA_OPTS variable that I use when I run java. An example is shown below
- TSTORE_OPT=”-Djavax.net.ssl.trustStore=”yourpath”/mytruststore
TPASS_OPT=”-Djavax.net.ssl.trustStorePassword=mypassword”
JAVA_OPTS=”${TSTORE_OPT} ${TPASS_OPT}”
java ${JAVA_OPTS} MyJavaProgram
In production I always store variables like these in a protected configuration file
I’ve used this approach successfully with stand-alone java applications, Tomcat, WebLogic and Jboss