Creating Trusted Self-Signed Certificates

Vinson Chuong
Scripting Bits
Published in
2 min readApr 2, 2021

When developing a web app and testing features that require HTTPS, the most straightforward way is to generate a self-signed certificate for localhost.

The problem with this approach is I have to click through pesky security warnings more often than I’d like.

Today, I’m going to implement a better solution.

Out of the box, browsers know which SSL certificates they can trust. Because there are an intractable number of possible domain and host names, it’s impractical to keep lists of all of them. Instead, browsers rely on a small number of certificate authorities. Certificate authorities are able to issue SSL certificates that are signed and can be traced back to them. Therefore, it suffices to keep a list of all of the certificate authorities.

As for self-signed certificates for localhost, getting browsers and other clients to trust them involves creating a certificate authority and adding it to the list.

Fortunately, this is a well trodden path. I can leverage OpenSSL to get this done.

First, I create a key and certificate for identifying my new certificate authority.

openssl genrsa -des3 -out ca.key 2048openssl req -x509 -new -nodes -key ca.key -sha256 -days 1825 -out ca.certopenssl pkcs12 -inkey ca.key -in ca.cert -export -out ca.pfx

I’ve also bundled the key and certificate together into a .pfx file, which is a commonly accepted format for clients.

For Chromium, adding the certificate authority to its trusted list can by done by navigating to Settings > Security > Manage certificates > Authorities.

For Firefox, Preferences > Privacy & Security > Security > Certificates > View Certificates… > Authorities.

From here, I can issue SSL certificates using my certificate authority. They will automatically be trusted by the browsers where I’ve registered my certificate authority.

First, I create a file localhost.ext with the following contents:

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost

Then, I run:

openssl genrsa -out localhost.key 2048openssl req -new -key localhost.key -out localhost.csropenssl x509 -req -in localhost.csr -CA ca.cert -CAkey ca.key -CAcreateserial -out localhost.cert -days 1825 -sha256 -extfile localhost.extopenssl pkcs12 -inkey localhost.key -in localhost.cert -export -out localhost.pfx

That’s an unusually long list of long commands.

--

--