Skip to content

Instantly share code, notes, and snippets.

Last active June 10, 2024 13:31
Show Gist options
  • Save cecilemuller/9492b848eb8fe46d462abeb26656c4f8 to your computer and use it in GitHub Desktop.
Save cecilemuller/9492b848eb8fe46d462abeb26656c4f8 to your computer and use it in GitHub Desktop.
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

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

keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @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.

Copy link

Certificate import error

The Private Key for this Client Certificate is missing or invalid

when i import certificate in chrome browser.

Copy link

Still Working!. Thanks @cecilemuller

Copy link

Note that if you are generating for localhost, in the commands for "Generate localhost.key, localhost.csr, and localhost.crt:" the CN in the first command should be ".../CN=localhost", not ".../CN=localhost.local" otherwise Chrome (and maybe others) won't like it.

Copy link

jaami commented Jan 7, 2022

Command: openssl x509 -req -sha256 -days 1024 -in localhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out localhost.crt

OutPut: C:\xampp\htdocs\SSL>openssl x509 -req -sha256 -days 1024 -in localhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out localhost.crt
Can't open "domains.ext" for reading, No such file or directory
78030000:error:80000002:system library:BIO_new_file:No such file or directory:crypto\bio\bss_file.c:67:calling fopen(domains.ext, r)
78030000:error:10000080:BIO routines:BIO_new_file:no such file:crypto\bio\bss_file.c:75:

for me all steps work smoothly otherwise useless effort wont help because things are new and confusing.

Copy link

@jaami: The domains.ext file must be located in the directory where the command is executed. Also check the file permissions for the executing user.

Copy link

I followed this

It's kind of a hack with heroku.

If you are going to follow that then some tips:

  • you have to implement the route asked in certbot console output, in your heroku app (not the app running on localhost. So, that letsencrypt can access that from their server)
  • add domain in /etc/hosts at the end

Copy link

In addition to comments on cert validity above, when you regenerate your certs from the CL, remember to restart your local web server prior to testing. If in doubt, check the dates on cert, issuer etc. If your cert is invalid, it's possibly because the web server is serving an older one, but your browser is validating against the new one in the store.

Copy link

burawi commented Aug 10, 2022

Need an easy solution:

Just amazing! Thank you @dol

Copy link

daxlai commented Nov 1, 2022

Still Working!. Thanks @ce

are you configure this with TOMCAT ? if yes please guide me i am unable to do it

Copy link

daxlai commented Nov 1, 2022

Using this method i am unable to SSL in tomcat 9. please explore it for tomcat 9 for localhost only or for local network

Copy link

Need an easy solution:

You saved my day! Thanks!

Copy link

magi-web commented Jan 8, 2023

Thank you so much ! It works like a charm <3

Copy link

peppeg85 commented Feb 8, 2023

hello, if i need to add more hosts in the future, i have to update the domain.ext file and re-generate the certificates with the two instructions

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

and another question: in the domain.ext file, the entries authorityKeyIdentifier=keyid,issuer how should be valorized?
thank you

Copy link

daxlai commented Feb 8, 2023 via email

Copy link

peppeg85 commented Feb 9, 2023

follow the guide, on windows you ave to add hosts inside the hosts


if you can't see it enable hidden files in the system explorer. then add entries like www.fake1.local (the entries inside the domains.ext file), do this with notepad++, it will ask you to save as administrator.

maybe you need to disconnect and reconnect windows.
if still doesn't work try to use CN=*.localhost.local for this instruction:

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"

then i use this with spring boot, so i had to convert the crt file to p12

Copy link

BraxtonI commented Feb 9, 2023 via email

Copy link

b-and-p commented Apr 14, 2023

Excellent information, thanks! I was struggling with Chrome and Wampserver for a week before I saw this. Worked like a charm!

Copy link

DragonOsman commented Jun 20, 2023

I want to do this for a MERN app I'm trying to develop and test locally that uses JWTs for authentication. Without HTTPS, the cookies would be ignored by the browser since I'd need to use secure cookies.

I think I successfully generated the .crt file using my .csr and .key files, but now when I try to visit https://localhost:3000 or https://localhost.local:3000 I get an error. What do I need to do from here?

Edit: I've installed the .crt file to the store (type of store left up to the wizard) and I've added "localhost" with port 3000 to my hosts, but it's still telling me that the site isn't secure when I try to visit it in MS Edge. Please help. Thanks.

Edit2: Okay, I've also added the cert file to the trusted store in mmc.exe but still doesn't work. I still get the error that the site isn't secure. What should I do?

Copy link

Wow awesome, thank you so much for your tutorial ! :)

Copy link

Thanks for your tutorial, it solve my problem!!

Copy link

pixelfast commented Sep 18, 2023

So, SSL on localhost now works fine, and displays the Wampserver Homepage.

I now have Your Virtual Hosts listed as:


In my httpd-vhosts.conf file, the entry looks like this:

<VirtualHost *:8080> ServerName mortgagequest DocumentRoot "c:/mysites/azmortgage/new" <Directory "c:/mysites/azmortgage/new/"> Options +Indexes +Includes +FollowSymLinks +MultiViews AllowOverride All Require local </Directory> </VirtualHost>

My hosts file has this entry: mortgagequest
::1 mortgagequest

When I browse to https://mortgagequest I get the Wampserver Homepage.

What further steps do I need to take to enable SSL for the virtual host?

Thank you!

Copy link

Is there a way to use the SSL certificate directly for localhost sites, without installing a web server of some sort? While I can go down that route, I'd rather stay with the simplicity of resolving things using "/etc/hosts"!

Copy link

perki commented Jan 25, 2024

@alpheus-madsen To serve HTTPS you need an web server.
As a one liner solution, if you have nodejs installed, do npx <path to serve>, this will provide a localhost SSL certificate plus a minimal web server.

Copy link

Unfortunately, I got this:

name is expected to be in the format /type0=value0/type1=value1/type2=... where characters may be escaped by . This name is not in that format: 'E:/xampp/Git/C=US/ST=YourState/L=YourCity/O=Example-Certificates/CN=localhost'
problems making Certificate Request

Honestly, I have no idea what I am doing :D, but I was successful using this:

Thanks to everyone sharing their knowledge!

Copy link

hgati commented Feb 23, 2024

Great thanks. Perfect solution !!

Copy link

daxlai commented Feb 25, 2024

here is my server.xml file ssl config part

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="150" SSLEnabled="true">
    <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
	  <Certificate SSLCertificateFile="localhost.crt"
       SSLCertificateKeyFile="localhost.key" />


Copy link

It worked with one more command addition to that. Found the solution here

openssl pkcs12 -export -out localhost.local.pfx -inkey localhost.local.key -in localhost.local.crt

localhost.local is the custom domain as an example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment