Saturday, June 14, 2014

OpenSSL Certificates to Tomcat Keystores

So being through this process a few times, and having to relearn it every time has not been fun. But before we get all technical let's do a little review. SSL/TLS allows clients/webbrowsers to securely communicate with servers. It utilizes public key cryptography (RSA or Elliptic Curve) to allow the server to hand out a key to the client. The client can then use that key to encrypt a message that only the server will be able to read (By decrypting it with a private key). This is great and all but unfortunately being able to securely communicate doesn't prevent the problem of communicating to the wrong person. This is where Certificate Authorities (CA) come into play. They verify that the person is who they say they are, and that they own the domain that the key is tied to. Once they have verified all that they "sign" the public key of the server with their private key. Now clients can obtain the public key (signed by the ca) from the server, and then use the ca's public key to verify that the signature was indeed from the ca, and then build trust that not only can they securely communicate with the server, but that they are communicating with the right server.
So in order to get started you have to create your private/public key pair. The public key will be the one that is handed out to everyone, and also the one that will be signed by CA's, while the private one will be kept only by you, and likely your server in order to decrypt all the traffic coming in, and also encrypt the traffic going back out.

openssl genrsa -out <yourdomain>-private-key.pem <key size in bits>

This command will generate a RSA keypair and save it with no password protection. Some common keysizes (from least secure to better secured) 1024, 2048, 4096.


openssl pkey -text -in <yourdomain>-private-key.pem
openssl pkey -in <yourdomain>-private-key.pem -pubout -text

These commands will pour out the different components of the key to the console. The first one generating the base64 encoded private key part, and the second one the base64 encoded public key part.

Ok, so now you have the keys that allow you to set up secure communication, the next step is to get your public key signed by a CA. CA's generally accept a certificate signing request (.csr), this consists of your public key, and a bunch of information about that key, most importantly is the "common name" or CN, which should resolve to your domain name. Mine being murphysean.com, or www.murphysean.com, and if your CA allows you could do *.murphysean.com to allow the certificate to work on all subdomains.

openssl req -out <yourdomain>.csr -key <yourdomain>-private-key.pem -new -sha256

The next command takes in the public/private key combo, a bunch of information from you on the command line, and pumps out a request that the CA can accept and sign to produce your final certificate. The -sha256 will request that the authority sign a sha256 hash of your public key combined with all the information gathered from you, you can leave it off to let it default to something more common. The more you pay the more the CA will be willing to certify. For most of your certificate authorities cheaper signing request options, they are only signing the CN. So don't be suprised when your final certificate has nulls for all the values you filled in.

cat <yourdomain>.csr

This will dump the csr text file to the console for easy copy and paste into your ca's web site form. At this point you should have the certificate from your CA. Save this file as <yourdomain>.crt

They will often also give you their root certificate, and sometimes their intermediate certificates as well. You'll want to nab those up at this time and save them. At this point you have all the pieces you need. I'll include some instructions for nginx at this point.
To get set up in java/tomcat you still have a bit of work to do. Tomcat uses a java keystore that should contain the server certificate. The first step in getting a keystore set up is to get your certificate into a a PKCS12 file. OpenSSL can do this for us.

openssl pkcs12 -export -in <yourdomain>.crt -inkey <yourdomain>-private-key.pem -out <yourdomain>.p12 -name <yourdomain> -CAfile <yourca>.pem -caname <yourcaname> -chain

This will merge all the different certificates into a chained pkcs12 file. You'll want to password protect the private key, with a password that is ok for your server application to know. Also as a side note here, if you were signed by an intermediate certificate, you'll want to obtain all the certificates that fall between you and the root certificate. Open the intermediate file in a text editor, and then just start appending all the certificates in order up to the root certificate. In many cases this is just the one root certificate as there is only one intermediate inbetween you and the root.

keytool -importkeystore -srckeystore <yourdomain>.p12 -srcstoretype PKCS12 -alias <yourdomain> -destkeystore <yourdomain>.keystore

So now you've got everything in order the last step is to just get your tomcat server pointed at your keystore for https/ssl/tls traffic. Open up your server.xml file, and uncomment the SSL Connector. I added two properties to mine, the keystoreFile property which I pointed at my .keystore file, and the keystorePass which unlocked the keystore, and also the private key in that keystore.

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="<pathtokeystore>.keystore"
keystorePass="<ubersecurepassword in plaintext>"/>

In tomcat 8 the final working Connector looked like the above.

No comments:

Post a Comment