Tuesday, December 30, 2008

How to Generate a Self-Signed Cert for Java cacerts and Apache

The following describes how to generate a self-signed cert in the java keystore and then export out the cert and key so that Apache can use it.

How to Check for an Expired Cert

Command-line Check for an Expired Cert

* Print expired cert date:
echo "" | openssl s_client -connect server:443 > certificate

Creating/Renewing key in cacerts

Note: Replace yourhostname in the following with your hostname or virtual hostname

Remove old cert

${JAVA_HOME}/bin/keytool -delete -alias yourhostname.yourdomain.com -keystore ${JAVA_HOME}/jre/lib/security/cacerts

Create new cert (-validity 40000 basically means it should last for many years)

${JAVA_HOME}/bin/keytool -genkey -alias yourhostname.yourdomain.com -keystore ${JAVA_HOME}/jre/lib/security/cacerts -keyalg rsa -validity 40000
Enter keystore password: changeit
What is your first and last name?
[Unknown]: yourhostname.yourdomain.com
What is the name of your organizational unit?
[Unknown]: Office of Information Technology
What is the name of your organization?
[Unknown]: Duke University
What is the name of your City or Locality?
[Unknown]: Durham
What is the name of your State or Province?
[Unknown]: North Carolina
What is the two-letter country code for this unit?
[Unknown]: US
Is CN=confluence-test.domain.org, OU=Office of Information Technology, O=Duke University, L=Durham, ST=North Carolina, C=US correct?
[no]: y

Enter key password for <yourhostname.yourdomain.com>
 (RETURN if same as keystore password):
If this fails with "keytool error: java.io.FileNotFoundException: ${JAVA_HOME}/jre/lib/security/cacerts (Permission denied)", you need appropriate permissions on cacerts:
cd ${JAVA_HOME}/jre/lib/security
chmod 644 cacerts
(repeat step above)

Exporting cert to apache using openssl

This info is from http://mark.foster.cc/kb/openssl-keytool.html * Once the alias has been identified we can do the extraction.
${JAVA_HOME}/bin/keytool -keystore ${JAVA_HOME}/jre/lib/security/cacerts -export -alias yourhostname.yourdomain.com > /tmp/yourhostname.der.crt
* The result is a DER (binary) formatted certificate in /tmp/yourhostname.der.crt. It can be viewed using:
openssl x509 -noout -text -in /tmp/yourhostname.der.crt -inform der
* You will want to convert it to another format - PEM - which is more widely used in applications such as apache and postfix.
openssl x509 -out /tmp/yourhostname.yourdomain.com.pem.crt -outform pem -text -in /tmp/yourhostname.der.crt -inform der
* The resulting file can now be referenced from apache, postfix, etc as the CA certificate.

Copy cert to Apache

* Copy key (/tmp/yourhostname.yourdomain.com.pem.crt) to apache cert dir as yourhostname.yourdomain.com.crt, and you'll probably want to back up the old file first
cp /etc/httpd/conf/ssl.crt/yourhostname.yourdomain.com.crt /etc/httpd/conf/ssl.crt/yourhostname.yourdomain.com.crt.old.todaysdate
cp /tmp/yourhostname.yourdomain.com.pem.crt /etc/httpd/conf/ssl.crt/yourhostname.yourdomain.com.crt

Exporting private key from cacerts to apache

_partially from_ _[http://mark.foster.cc/kb/openssl-keytool.html]_ * If you have Java 1.5 or later you may be able to use the attached class [ExportPriv.class|^ExportPriv.class] (go to Attachments and click on it to download it), or follow the instructions below to compile it on your own The original [ExportPriv|http://mark.foster.cc/pub/java/ExportPriv.java] crafted from Andrew Morrow's posting at [http://forum.java.sun.com/thread.jsp?forum=2&thread=154587&message=449486]. The key will be produced to STDOUT. Was suggested that you redirect > to exported.key

Compile ExportPriv.java

From http://mark.foster.cc/pub/java/ExportPriv.java crafted from Andrew Morrow's posting.
javac ExportPriv.java
java ExportPriv <keystore> <alias> <password> > exported-pkcs8.key

Extract the Private key

* The ExportPriv java command-line utility either needs to be run from the server itself, or you can scp its cacerts file to a different location to extract it.
scp /tools/*xport\* (server):/tmp
ssh and change ownership as needed
CLASSPATH=.
${JAVA_HOME}/bin/java ExportPriv ${JAVA_HOME}/jre/lib/security/cacerts yourhostname.yourdomain.com changeit > exported-pkcs8.key
* The private key is being exported as PKCS#8 PEM format. To get it into the RSA format that works with Apache (see below) you can issue the following command:
openssl pkcs8 -inform PEM -nocrypt -in exported-pkcs8.key -out yourhostname.yourdomain.com.key
Warning: don't make this key available anywhere publicly. That defeats the purpose of it (is supposed to be private).

Copy Key to Apache

* Copy key (yourhostname.yourdomain.com.key) to apache key dir, and you'll probably want to back up the old file first
cp /etc/httpd/conf/ssl.key/yourhostname.yourdomain.com.key /etc/httpd/conf/ssl.key/yourhostname.yourdomain.com.key.old.todaysdate
cp yourhostname.yourdomain.com.key /etc/httpd/conf/ssl.key/yourhostname.yourdomain.com.key

Updating Config of Applications that Use the Cert

* If you are using something else that uses that cert (in our case was Shibboleth), you may need to update all references to the cert and key in /etc/shibboleth/shibboleth.xml or you could just backup the old server.crt and server.key and overwrite them with the new one if it is the default server cert and key.

Restarting Apps

* After updating don't forget to restart any external services/apps using the cert

Updating Apache Config

* If needed, update the /etc/httpd/conf.d/ssl.conf or whichever conf file refers to the cert and key * If you're not sure where it is you could grep for it:
cd /etc/httpd/conf.d/
grep -H ".crt" *
grep -H ".key" *
* If you don't find it, you'll need to look into configuring apache with the key. Note: Watch out for external applications that maybe synchronizing configs such as Glump. It may overwrite your changes. Check to determine the proper way to update config.

Restarting Apache

/sbin/service httpd restart

Contact Anyone Who Might Care About a Cert Change

* In our case we needed to contact the Shibboleth IdP folks. You may want to suggest that a different self-signed cert be used for the SSO.

No comments: