How to Create Trusted SSL Certificates for Your Local Development

Generate trusted self-signed SSL certificates to enable HTTPS in your local development

Hicaro Adriano
Better Programming

--

Hands holding a device whose screen reads “SECURE SSL ENCRYPTION.”
Photo designed by Freepik.

Have you ever found yourself in a position where you needed to add HTTPS to your app running on localhost or some other local domain such as local.my-app.com?

Web browsers have subtle differences when running HTTP vs. HTTPS pages. For instance, on an HTTPS page, any attempts to load JavaScript from an HTTP URL will be blocked. This means that if you’re developing locally using HTTP, you might add a script tag that works just fine on your development machine, but it breaks when you deploy your app to staging or production, which will be running under HTTPS. Sigh…

Worry not, my friend. To avoid this sort of problem, it’s useful to set up HTTPS on your local environment to be able to mirror your production server more closely. However, it can be quite of a hassle to get it working. None of us want to see certificate warnings all the time. With that being said, how do you get the secure lock locally?

The answer to this question is to generate your own certificate, either self-signed or signed by a local root, and trust it in your operating system’s trust store. From there onwards, use that certificate in your local web server.

In this article, we will go through the process of generating a local root certificate (aka certificate authority). This allows you to generate as many domain name certificates as you want but only trust one certificate — the root one.

One important fact worth noting is that since September 1, 2020, SSL certificates cannot be issued for longer than 13 months (397 days). Therefore, we are sticking with 12 months for the certificates generated in this article.

Generating the Certificate

Certificate Authority (CA)

  1. Generate a private key and self-signed certificate:

Optional: You may replace MY-CA with something else of your choosing in CN.

If you want to check your certificate information, you may output its contents by running the following:

2. Create a .crt certificate file:

Domain name certificate

In the majority of cases, registering localhost alone within the certificate is enough. However, if you like to have custom domain names for your local apps, you may add one or more alternate names for the certificate you will be creating.

  1. Generate an x509 v3 extension file:

You may add as many domain names as you want following the same pattern as above.

Note: Please update DNS.4 , DNS.5 , and DNS.6 or remove them if you do not have any local domain names set up.

2. Generate a private key and certificate sign request (CSR):

Optional: Country, State, City, and Organization are customizable.

3. Generate a self-signed certificate:

Using the Certificate

You will have to provide the certificate and private key files onto the applications serving your content. This could be a local web server such as Apache or NGINX, a local service, or some other local tool like webpack DevServer.

Here are a few examples:

Apache

NGINX

webpack DevServer

Express.js

From the moment you configure whatever entity is serving your app to use your certificate, your app will be accessible under an HTTPS URL.

Following the Express example above, you may open a browser tab on https://localhost:8000 and see your content:

Opening browser on https://localhost:8000

Wait a second! Where is my “this is a secure server” message?

This is not what you were looking forward to seeing when loading the page, but this is expected since the CA is not trusted yet.

Trusting the CA

To get a secure lock, your new local CA has to be trusted in your machine. This process varies across operating systems and will suffice for most browsers. If you are using Firefox, the process varies a bit.

macOS — Chrome and Safari

  1. Double-click on the root certificate (ca.crt).
  2. Select your desired keychain (login if you intend to have it trusted only under your account or System if the certificate should be trusted system-wide).
  3. Add the certificate.
  4. Open “Keychain Access” (if it isn’t already open).
  5. Select the keychain you chose earlier.
  6. You should see the certificate MY-CA (it will be the name you gave as CN to your CA).
  7. Double-click on the certificate.
  8. Expand “Trust” and select the option “Always Trust” in “When using this certificate.”
Trusting the CA

9. Close the certificate window and type your user password (if required).

Windows 10 — Chrome, IE11, and Edge

  1. Double-click on the certificate (ca.crt).
  2. Click on the “Install Certificate” button.
  3. Select whether you want to store it at the user or machine level.
  4. Click “Next.”
  5. Select “Place all certificates in the following store.”
  6. Click “Browse.”
  7. Select “Trusted Root Certification Authorities.”
  8. Click “OK.”
  9. Click “Next.”
  10. Click “Finish.”
  11. If you get a prompt, click “Yes.”

Firefox

Even after trusting your CA certificate in your trust store, Firefox will still give you warnings about it. It may or may not happen on Windows 10, but it will most certainly happen on macOS. It is pretty straightforward from here. Firefox will display a screen as below:

Warning page on Firefox

To further allow your certificate, click on “Advanced…” Right after that, click on “Accept the Risk and Continue to acknowledge” you are aware of the risks.

This will only have to be performed once, but it is once per local domain.

Conclusion

After generating and trusting your certificate, you should be good to access your local domains without issues! Your apps can now be securely served and your development flow can go on. Going back to the Express example from earlier, this would be your result:

Example of secure server

The website is fully loaded and Chrome is now displaying the lock symbol next to the URL.

I hope this article helped solve one of your HTTPS hurdles. If there is anything else you’d like me to expand on to help you, please leave a note below. Additionally, let me know any similar problems I can help out with. Happy coding!

--

--

Software Developer. Angular, NodeJS and Golang enthusiast. Passionate for learning new things.