Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to create an HTTPS certificate for localhost domains

How to create an HTTPS certificate for localhost domains

This focuses on generating the certificates for loading local virtual hosts hosted on your computer, for development only.

Do not use self-signed certificates in production ! For online certificates, use Let's Encrypt instead (tutorial).

Certificate authority (CA)

Generate RootCA.pem, RootCA.key & RootCA.crt:

openssl req -x509 -nodes -new -sha256 -days 1024 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=US/CN=Example-Root-CA"
openssl x509 -outform pem -in RootCA.pem -out RootCA.crt

Note that Example-Root-CA is an example, you can customize the name.

Domain name certificate

Let's say you have two domains fake1.local and fake2.local that are hosted on your local machine for development (using the hosts file to point them to 127.0.0.1).

First, create a file domains.ext that lists all your local domains:

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

Generate localhost.key, localhost.csr, and localhost.crt:

openssl req -new -nodes -newkey rsa:2048 -keyout localhost.key -out localhost.csr -subj "/C=US/ST=YourState/L=YourCity/O=Example-Certificates/CN=localhost.local"
openssl x509 -req -sha256 -days 1024 -in localhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out localhost.crt

Note that the country / state / city / name in the first command can be customized.

You can now configure your webserver, for example with Apache:

SSLEngine on
SSLCertificateFile "C:/example/localhost.crt"
SSLCertificateKeyFile "C:/example/localhost.key"

Trust the local CA

At this point, the site would load with a warning about self-signed certificates. In order to get a green lock, your new local CA has to be added to the trusted Root Certificate Authorities.

Windows 10: Chrome, IE11 & Edge

Windows 10 recognizes .crt files, so you can right-click on RootCA.crt > Install to open the import dialog.

Make sure to select "Trusted Root Certification Authorities" and confirm.

You should now get a green lock in Chrome, IE11 and Edge.

Windows 10: Firefox

There are two ways to get the CA trusted in Firefox.

The simplest is to make Firefox use the Windows trusted Root CAs by going to about:config, and setting security.enterprise_roots.enabled to true.

The other way is to import the certificate by going to about:preferences#privacy > Certificats > Import > RootCA.pem > Confirm for websites.

@ctcherry

This comment has been minimized.

Copy link

commented Jun 20, 2018

I made a tool to help with some of this locally on OSX, it has some issues I would like to fix eventually such as needing to run with sudo, but its been working great for me so far. https://github.com/ctcherry/tlself

@AlexeyKot

This comment has been minimized.

Copy link

commented Jan 31, 2019

Thank you so much! I finally made it work only after your tutorial.

@Dibbyo456

This comment has been minimized.

Copy link

commented May 25, 2019

I've tried many tutorials none of them worked but this one finally did. 😍
Thank you so much. 🙏

@k-gun

This comment has been minimized.

Copy link

commented Jun 21, 2019

On Chrome, importing via "Authorities" tab solving probs.
Thank you.

@temuri416

This comment has been minimized.

Copy link

commented Jul 8, 2019

How do you install these certs for nginx? Thanks!

@k-gun

This comment has been minimized.

Copy link

commented Jul 10, 2019

@temuri416, here is my local config stuff (for nginx version: 1.16.0);

# file: /etc/nginx/sites-available/default.conf
server {
  listen 80;
  listen 443 default ssl;

  #ssl on; ###[warn] the "ssl" directive is deprecated, use the "listen ... ssl" directive instead in ...
  ssl_certificate      /home/kerem/.ssl/localhost.crt;
  ssl_certificate_key  /home/kerem/.ssl/localhost.key;
  ...


# file: /etc/nginx/sites-available/mysite.local.conf
server {
  listen 80;
  server_name mysite.local;
  return 301 https://mysite.local$request_uri;
}
server {
  listen 443 ssl http2;
  
  ###[warn] the "ssl" directive is deprecated, use the "listen ... ssl" directive instead in ...
  #ssl on;
  ssl_certificate      /home/kerem/.ssl/localhost.crt;
  ssl_certificate_key  /home/kerem/.ssl/localhost.key;
  ...

Remember to check after saving config files with nginx -t.

@temuri416

This comment has been minimized.

Copy link

commented Jul 11, 2019

@k-gun

I tried that. I cannot make it work following the steps. When did it work for you last?

@monoteos

This comment has been minimized.

Copy link

commented Aug 8, 2019

Best tutorial on internet on how to make it work on localhost, thanks!

@Shaftoe62

This comment has been minimized.

Copy link

commented Aug 9, 2019

With this I FINALLY got it working! Thanks a 1.000.000

@sushmitpalrishi

This comment has been minimized.

Copy link

commented Aug 18, 2019

out of all the tutorials only this worked till now, after Facebook's march update. Thanks a lot for this

@alecos71

This comment has been minimized.

Copy link

commented Oct 8, 2019

The only working guide!!! Fantastic! I have all browsers with green padlock, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.