The Pragmatic Addict

Create Your Own Certificate Authority

Background

Much to my pleasure, many home based devices (routers, media players, IoT etc) are moving away from unencrypted HTTP and moving to HTTPS. To their credit each is generating it’s own self signed certificate. That in of itself is fine however you have to tell your browser to trust every cert. If you are one of those using Firefox for Android, you have to manually override every time (annoying).

What I needed was a certificate authority. Yes, I know about Let’s Encrypt, it’s a wonderful free service. The downside is those public certificates have to be renewed every X months and the devices has to be internet facing (Requiring a static IP & DNS entry). Unfortunately routers don’t use the ACME protocol (yet?).

Goals:

I’ve managed to narrow down the entire process to two script files using OpenSSL

Create the Certificate Authority

The below script should only be run once to generate your CA key pair. Warning: If you run this a second time it will wipe all of your generated keys!

create-ca.sh

#!/bin/bash
rm cacert.srl
rm -rf keys
openssl genrsa -out cakey.pem 2048
openssl req -x509 -new -nodes -key cakey.pem -sha256 -days 36500 -out cacert.pem -subj '/C=US/ST=New York/L=New York/O=Acme/CN=Acme CA'
mkdir keys

Generate a server key pair and sign with CA

The below script will generate key pairs in PEM format. Be sure to specify your fully qualified hostname or the certificate may not work.

gen-key.sh

#!/bin/bash
if [ "$1" == "" ]; then
    echo "Specify FQDN host name"
    exit
fi
openssl genrsa -out "keys/$1-key.pem" 2048
openssl req -new -subj "/C=US/ST=New York/L=New York/O=Acme/CN=$1" -key "keys/$1-key.pem" -out "keys/$1.csr" 
openssl x509 -req -CAcreateserial -CA ./cacert.pem -CAkey ./cakey.pem -in "keys/$1.csr" -out "keys/$1-cert.pem" -extfile <(printf "subjectAltName=DNS:$1")
rm "keys/$1.csr"

Install your CA certificate

This will let your browser know it’s ok to trust your newly minted key pairs.

Debian OS (and Dillo)

Run the following commands to install. You must use a unique name for the .crt file

openssl x509 -inform PEM -in cacert.pem -out /usr/local/share/ca-certificates/myca.crt
update-ca-certificates

Android (15) & Chromium

Firefox for Android

Thanks to The Jeroen HD blog for these instructions.

Firefox for Linux

Chromium for Linux

Install your server certificate

In most cases the PEM format is fine but there are exceptions:

OpenWRT

These keys need to be converted to DER format. I added the following lines to gen-key.sh

openssl x509 -in keys/$1-cert.pem -outform DER > "keys/$1-uhttpd.crt"
openssl x509 -in ./cacert.pem -outform DER >> "keys/$1-uhttpd.crt"
openssl rsa -in keys/$1-key.pem -outform DER > "keys/$1-uhttpd.key"

Once done copy the two files to /etc/uhttpd.crt & /etc/uhttpd.key on the device and reboot.


Created: 2025-04-15 Modified: 2025-04-16