Creating a CA for mTLS with OpenSSL

In this article I will explain how I created my own certificate authority and issued certificates to use for my Zookeeper setup. Thus, I also go into detail about how to convert certificates to use in a Java application.

To give a bit of background, I started working recently on a personal project to deploy Zookeeper on Kubernetes. One feature of Zookeeper that I was interested in is TLS encryption on connections and using mTLS for authentication. I some needed TLS certificates and I decided to roll my own.

For an introduction to mTLS, check out this article:

I decided that I’m going to use a single CA for all certificates. The advantage of this setup is that I only have to add a single CA certificate to my container images. The drawback is how to handle certificate revokation, for example if a key is compromised or a certificate is decommissioned. This is out of the scope of this article.

Creating a CA

I used OpenSSL to create a certificate authority and some certificates. With OpenSSL, I prefer supplying all configuration via config files. What I found very valuable is the .include directive, that allows me to share a base config with all the certificate-specific entries delegated to different files.

Preparing the CA home

To create the CA repository, in a separate directory, create a directory and initialize it with some subdirectories and files:

For the CA, I wanted to define some sensible defaults:

  • Certificates are issued for 1 year;
  • I use SHA512 as the message digest;
  • commonName is for humans, and all other fields are absent.
  • Any DNS and IP constraints are delegated to the subjectAltName extension.

Then, create a configuration file for your repository:

openssl.conf:

Creating the CA certificate

Create a configuration for your CA certificate:

ca.conf:

Create a key for your CA, with a secure password in private/ca-key.pem:

Create the self-signed CA certificate:

Creating the mTLS certificate for Zookeeper

Create a configuration for your zookeeper certificate:

zookeeper.conf:

Note: you can also add ip address restrictions by adding IP.1 = 192.168.x.x, IP.2 = ... lines to the x509_subject_alt_name section.

Create a key for your certificate:

Create the certificate and sign with your CA:

Note: the subject of the certificate is supplied on the command line, and the subject_alt_name section is in the configuration file.

Sign the certificate with your CA:

Note: the -create_serial switch is only needed the first time you are issuing a certificate, and should be omitted subsequently.

To use this certificate in Java, we must convert it to PKCS12 or JKS (Java KeyStore) format. Oddly enough, to import a key into JKS, this can only be done from a PKCS12 file:

Also import your CA certificate:

Note: I use the password changeit here, which is the default password for the JDK CA certificate store as well. Make sure to use a secure password!

I hope you enjoyed this article!

Comments

Popular posts from this blog

Disk encryption with SSH remote unlocking on Debian 11

Java and TLS certificates