As more and more of the web moves to https, we developers find more problems getting things to run properly.
It used to be easier to run development sites on http and maybe have a config option pretending it was secure, or use a fake certificate (often labelled “snakeoil”)
As the internet has matured this has become more problematic.
Some things just don’t work without https, browsers are less likely to let you ignore the warning, and if you develop a PWA it just won’t work without a valid, trusted certificate.
Easy solution - use Let’s Encrypt
It may not be obvious but you can create a free valid cert using Let’s Encrypt
This requires you control a domain - but you can then use it to add a public DNS record for a private internal IP address.
The advantage of this method is that the certificate will be valid on (nearly) all devices
Create Your own Root Certificate Authority
If you don’t have a domain or for reasons of company politics the above isn’t possible..
You can create the keys for your own Certificate Authority - and then sign as many https certificates as you like.
Normal Certificate Authorities have been going for many years and have their public keys embedded in all browsers - these are then used by the browser to recognise and validate regular certs.
Your keys don’t have this advantage and the hard part is that you need to install them on any device you need to use.
Create Root Key
Attention: this is the key used to sign the certificate requests, anyone holding this can sign certificates on your behalf. So keep it in a safe place!
openssl genrsa -des3 -out rootCA.key 4096
If you want a non password protected key just remove the
Create and self sign the Root Certificate
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt
Here we used our root key to create the root certificate that needs to be distributed in all the computers that have to trust us.
Import this into your browser
This only works for browsers you control
I tried importing to my OS certificates but that didn’t work for me
Importing my rootCA.crt to the browsers did work (eventually)
You only have to do this once - then you can create as many https certs as you want (say one for each project) and they will be recognised.
Create a certificate
This procedure needs to be followed for each server/appliance that needs a trusted certificate from our CA
My example is for a local dev server where I have a matching entry in my /etc/hosts file for the IP
Create the certificate key
openssl genrsa -out dot.burlington.me.uk.key 2048
Create the signing (csr)
The certificate signing request is where you specify the details for the certificate you want to generate. This request will be processed by the owner of the Root key (you in this case since you create it earlier) to generate the certificate.
Important: Please mind that while creating the signign request is important to specify the
Common Name providing the IP address or domain name for the service, otherwise the certificate cannot be verified.
You also need to specify a SAN / subjectAltName or chrome wont accept it
openssl req -new -sha256 \ -key dot.burlington.me.uk.key \ -subj "/C=UK/ST=Dorset/O=Tangible Bytes Ltd/OU=Development/CN=dot.burlington.me.uk" \ -reqexts SAN \ -config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:dot.burlington.me.uk")) \ -out dot.burlington.me.uk.csr
Verify the csr’s content
openssl req -in dot.burlington.me.uk.csr -noout -text
Generate the certificate using the custom csr and key along with the CA Root key
openssl x509 -req -extfile <(printf "subjectAltName=DNS:dot.burlington.me.uk") \ -days 120 \ -in dot.burlington.me.uk.csr \ -CA rootCA.crt \ -CAkey rootCA.key \ -CAcreateserial \ -out dot.burlington.me.uk.crt \ -sha256
Verify the certificate’s content
openssl x509 -in dot.burlington.me.uk.crt -text -noout