Generating self-signed certificate

localhost-ing

Suriya
Javarevisited
4 min readNov 13, 2022

--

Almost all the website today runs on https, to help encrypt the data transmitted between the website’s client and the website’s server.

The following post explains why we need SSL and steps for signing CA signed cert.

Contents

  1. Pre requisite
  2. Sample web app on default http
  3. Generating self signed public key certificate
  4. Generated Certificate Verification
  5. Importing the generated Key & Certificates into the server
  6. Setting the local device to trust the certificate

Lets see how we can generate our own self-signed cert and trust them in our development environment.

Note Avoid using self-signed certificate in Production. A separate list of steps will be required for the production setup.

Pre requisite

  1. Openssl CLI to generate Keys and Certificates. (Required)
  2. KeyStore Explorer (not mandatory)
  3. Nginx server (for demonstration)

Sample web app on defult http

For the demonstration purpose we will be using nginx default web running on port 8080, and the same will be applicable for other servers, however the server side configuration differs.

The browser indicates that it is not secured running on http

Generating Self signed Public Key Certificate

We would be generating and using a Private Key and a Public Key Certificate on our nginx servers.

To understand what Keys and Certificates are,

Now we know what we want, so lets generate the Private Key DomainKey.pem using the following command.

openssl genrsa -out DomainKey.pem 4096

Issue the following to generate a Self signed certificate using the above generated Private Key DomainKey.pem

openssl req -new -x509 -sha256 -days 1000 -addext 'subjectAltName = IP:172.24.0.1' -key DomainKey.pem -out DomainCert.pem 

here, we are adding an extension,

subjectAltName — either add a DNS=*.yourdomain.com or IP addresses as IP.1=x.x.x.x, IP.2=y.y.y.y or just IP=172.24.0.1.

eg. example providing my Local IPV4(use ipconfig/ifconfig) in SAN.

Note — Domain Name in the CN is no longer required, use SAN instead.

Verify Certificate

You can use openssl command to view the cert details. However, for this post we will import the DomainKey.pem into KeyStore explorer.

It is called self-signed for a reason

Here, if we see the issuer has signed the subject, both being the same. So, we have successfully created a self signed certificate.

DomainCert.pem with corresponding SAN in the Extention
DomainCert.pem with Basic Constraint showing CA

Importing the key & cert into the server

As we got our certificates in the previous step. We can install them in our nginx server. In our nginx.conf, uncomment the https section

    # HTTPS server
#
server {
listen 8443 ssl;
server_name localhost;

ssl_certificate C:\\Suriya\\nginx-1.22.1\\cert\\DomainCert.pem;
ssl_certificate_key C:\\Suriya\\nginx-1.22.1\\cert\\DomainKey.pem;

location / {
root html;
index index.html index.htm;
}
}

Now restart the server and access the localhost via 8443. Bingo!!

Click on Advanced and Proceed to localhost
on https but browser thinks that the cert cannot be trusted

Trusting the generated Certificate

Now we need to tell the browser that the public key certificate can be trusted.

Get into the browser setting and search for certs, here we are using Chrome.

Select mange device SSL certificate
Import DomainCert.pem as Trusted Root Certificate
Once imported, it shows up in here

Note This whole importing step can be avoid if we have our certificate signed by a Verified Certificate Authority which the browser trusts.

Now, the device’s browser should trust the website at 172.24.0.1 running on 8443, open an incognito window and check the status.

The browser is now happy since, we added our DomainCert.pem cert as Trusted

If you would like to simulate the Certificate Authority signing, feel free to check the below post,

Happy localhost-ing!

--

--

Suriya
Javarevisited

I am a full-time Software Engineer and a passionate Landscape Photographer. For more info visit https://suriyaprakhash.com