Simon Karman

Software Engineer and Game Developer

Generating Self Signed Certificates

A step by step explanation on how to generate your own self signed certificate for personal development purposes

Published on 2020-01-22

Created by Simon Karman

Generating Self Signed SSL Certificates

Nowadays almost all traffic between applications should use HTTPS. When developing a new application it can be a bit of a hassle to set this up, so sometimes it is skipped on the development environment and only applied on production environments, while I believe that even during the development of your own applications it is generally a good idea to build it using HTTPS. This not only makes your development environments more safe, it also saves you from weird bugs and discoveries that will have to be fixed once you see that the things you build work differently (or event don't work at all) when using HTTPS.

However, setting up HTTPS on your local machine can be cumbersome. I noticed that most information regarding HTTPS on the internet only partially explains how to properly setup HTTPS traffic on your local machine. What also doesn't help in this case is that those different online resources all seem to use their own terminology for the same things. That's why I though it would be nice share how I think you should setup HTTPS on your local machine for development perposes in this article (obligatory link to xkcd: https://xkcd.com/927/). I hope you like it.

Webserver (example in Express)

A prerequisite of using HTTPS is the need of an SSL certificate. In the configuration of most webservers you have to point to two files, the first is the key which contains your private key and secondly a crt file which contains your certificate.

Below is an example of how to setup https for you express application in NodeJS (please reffer to the documentation of your own webserver or framework on how to enable https).

const privateKey  = fs.readFileSync('certs/server.key', 'utf8');
const certificate = fs.readFileSync('certs/server.crt', 'utf8');
const credentials = { key: privateKey, cert: certificate };
var httpsServer = https.createServer(credentials, app);
httpsServer.listen(443);

Getting Started

Please follow the steps below to generate a self signed certificate which can be used for local development. These example assume that the two certificate files should be called server.key and server.crt and should both end up in the certs directory. If you need them somewhere else, the easiest thing to do it to just follow the steps below and aftewards copy them your the destination of your choice.

In our example the server expects the private key (certs/server.key) and the certificate (certs/server.crt) to be located in the certs directory. Please make sure that this directory is included in your .gitignore file to ensure that your private key is not accidentally pushed to your repository for everyone to see.

Ensure the certs directory exists and otherwise create it using the following command:

$ mkdir certs

Make sure you execute all following commands in this tutorial from this certs directory.

Root certificate

First we need to generate a root Certificate Authority. This will be root certificate of your certificate chain. You can also use an existing one if you already have one, thats why we generate it in your home folder. You can reuse it for all your development projects. Keep this file secure because it is the private key. Execute the following to command to first create the private key of the root CA (.key) and then create the public key (.pem) of the root CA.

$ mkdir ~/.karman/
$ openssl genrsa -out ~/.karman/rootCA.key 2048
$ openssl req -x509 -new -nodes -key ~/.karman/rootCA.key -sha256 -days 3650 -out ~/.karman/rootCA.pem

You can replace the occurence of .karman with something of your liking. This is just the directory name where your root certificate will be stored.

The pem file that was just generated should be added to your applications (for example Google Chrome). These applications will then trust all certificates that use it as their root certificate. This is another reason why it is usefull to use one root for all your applications. Only needing to add one certificate to each of your applications is easier.

Configuration

Secondly we need to create two files. One is the config for the certificate request and the other one is the extension file including the subject alternative names (SAN) of your domain.

Create both files as described below and fill in the values for countryCode, stateName, cityName, organisation, organisationUnit, emailAddress, CN, and DNS.1. The CN and DNS.1 are very important since these tell the certificate on which subdomain and domain the certificates can be used. If you own the domain example.org and your server is running on the app subdomain, then you should use the app.example.org value for the CN and the same for the DNS.1 name.

# certs/server.csr.cnf
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

[dn]
C=countryCode
ST=stateName
L=cityName
O=organisation
OU=organisationUnit
emailAddress=email@example.com
CN=app.example.com

# certs/v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = app.example.com

Generation

Now we can generate the private key: server.key. Using the command below and enter a pass phrase when requested.

$ openssl req -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout server.key -config <( cat server.csr.cnf )

Finally generate the self signed certificate: server.crt

$ openssl x509 -req -in server.csr -CA ~/.karman/rootCA.pem -CAkey ~/.karman/rootCA.key -CAcreateserial -out server.crt -days 3650 -sha256 -extfile v3.ext

That should be everything. Make sure that you can reach your application over the provided dns name (for example: app.example.com) and enjoy your HTTPS webserver!

Similar projects
If you like projects like this one you might also be intersted in other certificates-, https-, javascript-, and security-projects.
Generating Self Signed Certificates (generating-certificates)
Generating SSL Certificates