In this article, we will explore how to create your own Certificate Authority (CA) and use it to generate certificates for securing your website in a localhost development environment.

Why Use HTTPS for Localhost Development?

  • Mimics Production Environments: Most production websites and applications rely on HTTPS. Developing with HTTPS ensures that you can catch potential issues early and simulate the production environment accurately.
  • Access to HTTPS-Only Browser Features: Modern web features, such as Web Push Notifications and Progressive Web Apps (PWAs), are restricted to secure (HTTPS) connections. Developing with HTTPS unlocks these capabilities.
  • Testing Secure Cookies: Secure cookies (marked with the Secure attribute) are only sent over HTTPS connections. Using SSL locally allows you to test and validate secure cookie behavior, which is important for security-sensitive applications.
  • Improved Compatibility with Third-Party Services: Many APIs and third-party services require HTTPS. Testing integrations on an HTTPS-enabled localhost helps prevent compatibility issues during production deployment.

Generating a Root CA Certificate

A Certificate Authority (CA) is an organization or entity that validates the identity of a website, email address, company, or individual and issues digital certificates. These certificates confirm online identities and establish trust.

Most devices, browsers, and applications come pre-installed with root certificates from publicly trusted CAs such as Let’s Encrypt, DigiCert, and others.

However, these publicly trusted CAs do not issue certificates for websites using the localhost domain. To secure a locally hosted website, you need to create your own Certificate Authority (CA) and use it to issue SSL/TLS certificates for the website.

Install Necessary Software

To generate public and private keys, you need software capable of performing cryptographic operations. OpenSSL is an open-source cryptographic toolkit widely used to:

  • Generate public and private keys.
  • Create Certificate Signing Requests (CSRs).
  • Generate X.509 certificates.

To install OpenSSL on Debian-based operating systems, use the following command:

sudo apt install openssl

Creating a Self-Signed Certificate

This guide will walk you through the steps to create a root certificate using an Elliptic Curve (EC) private key, which is more secure and efficient than an RSA key. An EC private key is used to generate shared secrets via the Elliptic Curve Diffie-Hellman (ECDH) algorithm.

Before generating the private key, you need to check which elliptic curves are supported on your platform. Run the following command to list all available curves:

openssl ecparam -list_curves

Next, use one of the supported elliptic curves to generate your EC private key. For example, to use the prime256v1 curve, run:

openssl ecparam -name prime256v1 -genkey -noout -out private.key

With the private key generated, you can now create your self-signed root certificate. Use the following command:

openssl req -new -x509 -key private.key -days 365 -out public-key.crt

You will be prompted to provide details such as:

  • Country Code
  • Organization Name
  • Common Name

Fill in the required information to complete the creation of your self-signed root certificate.

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:IN
State or Province Name (full name) [Some-State]:.
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Diversify India
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:Diversify India
Email Address []:

Brief Explanation of OpenSSL Parameters

  • ecparam: An OpenSSL subcommand used to manipulate or generate elliptic curve (EC) parameter files.
  • -list_curves: Lists all currently implemented EC parameters.
  • -name: Specifies the “short” name of the EC parameters to be used.
  • -genkey: Generates an EC private key using the specified parameters.
  • -noout: Suppresses the output of the encoded version of the parameters.
  • -out: Specifies the output file. If not provided, the default is stdout.
  • req: A subcommand used to create and process certificate signing requests (CSRs) in PKCS#10 format. It can also create self-signed certificates for root CAs.
  • -new: Generates a new certificate request.
  • -x509: Outputs a certificate instead of a certificate signing request.
  • -key: Specifies the private key to sign a new certificate or CSR.
  • -days: When used with -x509, it specifies the number of days the certificate is valid. The default is 30 days.

Installing the Root Certificate on Devices

Once your root certificate is generated, you need to install it on the device where you are accessing your localhost website. The installation location depends on your development setup:

  • For Virtual Machines (VMs): Install the certificate in the operating system of the virtual machine if you access the website within the VM.
  • For Host Machines: Install the certificate on the host machine if you are accessing the localhost website from there.
  • For VMs with Port Forwarding: If you are developing on a virtual machine but using port forwarding to access the website on your host machine, the certificate needs to be installed on the host machine.

How to Install a Root Certificate in Linux

If you’re using a Linux operating system, follow these steps to install a root certificate:

# Ensure the ca-certificates package is installed
sudo apt install ca-certificates

# Copy the certificate to the /usr/local/share/ca-certificates directory
sudo cp public-key.crt /usr/local/share/ca-certificates/

# Update the certificate store
sudo update-ca-certificates

Run the following command to confirm the certificate is properly installed:

awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt | grep "Your Certificate Name"

Replace "Your Certificate Name" with the common name (CN) of your certificate (e.g., "Diversify India").

How to Install a Root Certificate in macOS

If you’re using macOS, you can install a root certificate using either the Keychain Access app or the command-line interface (CLI). In this example, we’ll demonstrate how to add a root certificate via the command line using the security command. To begin, open Terminal by navigating to Applications > Utilities > Terminal. Then, you can add the certificate manually by running the following command:

sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain public-key.crt

Use the following command to check if the certificate is installed correctly:

sudo security find-certificate -c "Your Certificate Name" /Library/Keychains/System.keychain

Replace "Your Certificate Name" with the common name (CN) of your certificate (e.g., "Diversify India").

Below is the explanation of each macOS command parameter.

  • sudo: Executes the command with superuser privileges (requires administrator password).
  • security: The macOS command-line tool for managing keychains and certificates.
  • add-trusted-cert: Add trusted certificate(s).
  • -d: Indicates the certificate is added to the System keychain (you can omit this if you want to add it to the Login keychain).
  • -r trustRoot: Marks the certificate as trusted to act as a root certificate.
  • -k /Library/Keychains/System.keychain: Specifies the keychain where the certificate will be added.

How to Install a Root Certificate in Windows

If you are using Windows 10 or 11, follow these steps to install a self-signed root certificate on your PC:

  1. Search for and open the Run application (or press Windows + R to open it).
  2. Type mmc and click OK to open the Microsoft Management Console (MMC).
  3. In the MMC window, go to File > Add/Remove Snap-in.
  4. Select Certificates and click the Add button.
  5. Choose Computer Account and click Next.
  6. Select Local Computer, then click Finish.
  7. Click OK to return to the MMC window.
  8. In the left panel, expand Certificates (Local Computer) and go to Trusted Root Certification Authorities.
  9. Right-click on Certificates and select All Tasks > Import.
  10. Click Next, then click Browse.
  11. Select your root certificate file (e.g., public-key.crt) and click Open.
  12. Choose Place all certificates in the following store (the default is Trusted Root Certification Authorities) and click Next.
  13. Click Finish to complete the import process.
  14. Restart your PC to apply the changes.

Finally, check that your CA certificate is listed under Trusted Root Certification Authorities > Certificates to confirm the certificate installation.

Check Certificate in Microsoft Management Console
Check Certificate in Microsoft Management Console

Generate SSL Certificate for a Localhost Domain

Once you are a trusted Certificate Authority (CA) on all your devices, certificates generated using your CA’s private and public keys will no longer trigger an “invalid certificate” warning.

Note that the CA issues a certificate containing their public key. This issued certificate is digitally signed with their private key to confirm that they have verified the applicant’s identity.

First, create an EC private key for your development website using the following command:

# Best practice: Use the domain name for output files.
# This makes it easier to manage certificates for multiple sites.
openssl ecparam -name prime256v1 -genkey -noout -out diversifyindia.key

Generate a Certificate Signing Request (CSR) file using the private key:

openssl req -new -key diversifyindia.key -out diversifyindia.csr

You will be prompted to provide information related to your development website.

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:IN
State or Province Name (full name) [Some-State]:.
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:.
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:diversifyindia.localhost
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Browsers require an x.509 v3 certificate with Subject Alternative Names (SAN) for HTTPS connections. Create a certificate extension file, defining SANs for the certificate. Below is an example of an extension file for the localhost domain:

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = diversifyindia.localhost
DNS.2 = www.diversifyindia.localhost

The alt_names section in the certificate extension file is very important. In this section, you must specify the domain names for which the certificate will be valid. For example, this file secures diversifyindia.localhost and www.diversifyindia.localhost. You can also include localhost without any subdomains.

Finally, create an SSL certificate using the command below:

openssl x509 -req -days 90 -CA public-key.crt -CAkey private.key -CAcreateserial -in diversifyindia.csr -extfile diversifyindia.ext -out diversifyindia.pem

This is how you can generate a valid SSL certificate for a locally hosted website.

Enable SSL Support for Your Localhost Website

You can now use the diversifyindia.key and diversifyindia.pem files with your server software (NGINX or Apache) to enable HTTPS support.

Install SSL for Localhost on Apache2 Server

Copy the .key and .pem files to the /etc/ssl/apache2/ directory, and create a site configuration file with the following settings to enable SSL for the localhost domain on the Apache server.

# Serve website on port 443
<VirtualHost *:443>
    ServerName www.diversifyindia.localhost
    ServerAlias diversifyindia.localhost
    DocumentRoot /var/www/html/wordpress

    <IfModule dir_module>
        DirectoryIndex index.php index.html
    </IfModule>

    # Enable SSL engine
    SSLEngine on
    SSLCertificateFile /etc/ssl/apache2/diversifyindia.pem
    SSLCertificateKeyFile /etc/ssl/apache2/diversifyindia.key
</VirtualHost>

You can use the above configuration to set up SSL on XAMPP as well.

Install SSL for Localhost on NGINX Server

Copy the .key and .pem files to the /etc/ssl/nginx/ directory, and add the following server block to enable SSL for the localhost domain on the NGINX server.

server {
    # Listen on port 443 for IPv4 and IPv6 connections
    listen 443 ssl;
    listen [::]:443 ssl;

    # Define your domain name
    server_name    www.diversifyindia.localhost diversifyindia.localhost;
    # Set the root directory for your WordPress site
    root           /var/www/html/wordpress;

    # Specify the index files to be used
    index          index.php index.html;

    # ECDSA certificates
    ssl_certificate /etc/ssl/nginx/diversifyindia.pem;
    ssl_certificate_key /etc/ssl/nginx/diversifyindia.key;

    # Use strong ciphers
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_buffer_size 8k;

    # Handle PHP files
    location ~ \.php$ {
        include                 fastcgi.conf;
        fastcgi_pass            php_fpm82;
    }

    # Use try_files to handle requests and execute PHP files if needed
    location / {
        try_files         $uri $uri/ /index.php?$args;
    }
}

After making changes to your server configuration, restart the web server to apply the updates.

For more details on securing your production website with a free SSL certificate, refer to our article on installing a free SSL certificate using Let’s Encrypt and acme.sh.