Thursday, February 19, 2015

Self-signed SSL, that precious green padlock

SSL, that's what I want, the green padlock on my browser. For public facing services, you just pay for a certificate. However, when it's about internal services, you can achieve all needed functionality with a self-signed one. The problem is that I always forget how to do it and spend hours searching online and trying stuff. That's why I've finally decided I should write this down.

Below is what I want to achieve,
  • Create my own certificate authority (CA).
  • Create my own self-signed certificate.
  • Allow the certificate to handle multiple domains.
  • Make use of SHA2.
The benefits of creating my own CA is that later I can import its certificate into my machines and all signed certificates will be trusted. This, the certificate supporting the right domain, and a high enough level of encryption is the path to the green padlock.

Before we start, I should point out that I'm not doing anything new here, I'm just putting together bits and pieces from very useful sources I've found online. Please find the references at the end of the blog post.

Tweaking OpenSSL's configuration

One of our goals is to create a certificate that will support multiple domains, meaning that a service can be accessed by the names of, or just * For that we need to tweak our OpenSSL's configuration. You can create a custom one or just edit the system-wide OpenSSL config. I went for the latter approach and in my case using Mac OS X, the configuration file was located in /System/Library/OpenSSL/openssl.cnf.

Look for the [req] section and add,
req_extensions = v3_req

Look for the [ v3_req ] and add,
[ v3_req ]
subjectAltName = @alt_names

Under the [ v3_req ] section, create a new [alt_names] one by writing,
DNS.1 =
DNS.2 =
DNS.3 = *
IP.1 =
IP.2 =

Please not the usage of * as a wildcard to allow the certificate to be valid for all subdomains under

Creation of our own CA

We create the key for our CA
openssl genrsa -out ca.key 4096

And then we create the CA certificate
openssl req -new -x509 -sha256 -days 1826 -key ca.key -out ca.crt

Creation of the self-signed certificate

We create a key for the certificate
openssl genrsa -out cert.key 4096

We issue the request
openssl req -new -key cert.key -out cert.csr

We sign it with our own CA
openssl x509 -req -sha256 -days 730 -in cert.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out cert.crt -extensions v3_req

In case you went for the option of not modifying the system-wide OpenSSL configuration and instead creating a new one, you should append the following string to the last command: -extfile /path/to/your/openssl.cnf

SSL certificate installation

Now that we have the certificate, we just need to install it on our servers. I won't cover this as it is well explained on some articles that you can find online. For installing it on NGINX, I've used Josh Reichardt's article.

CA's certificate installation

By now we should have our server serving content over SSL using our self-signed certificate. In order for our browsers to trust our certificate, our operating system should trust our CA. If we want to access the service programmatically (e.g. through a Java-based client), we should also tell our SDK to trust it. Let's do both.


Trusting a certificate in different operating systems is not within the scope of this post. However, if you happen to be on a Mac, go to Keychain access > System > Certificates > [Click on the + sign] > [Open ca.cert] > [Add it].

Java SDK

For Java to trust our CA certificate, it has to be added to the cacerts store. This can be done with the following command,

sudo keytool -import -trustcacerts -file ca.crt -alias my-own-CA -keystore $JAVA_HOME/jre/lib/security/cacerts


As I mentioned at the beginning, this post is based on some great resources I've found online. Thank you to the people that invested their time in providing them. Please find the links below.

No comments:

Post a Comment