How can I create a self-signed cert for localhost?
Asked Answered
M

14

219

I've gone through the steps detailed in How do you use https / SSL on localhost? but this sets up a self-signed cert for my machine name, and when browsing it via https://localhost I receive the IE warning.

Is there a way to create a self-signed cert for "localhost" to avoid this warning?

Mccready answered 17/11, 2011 at 15:43 Comment(5)
Did you install the certificate as a CA?Rush
I followed the process to install a self-signed cert into IIS under Win7. But that creates the cert for "mymachinename", and I need one for "localhost".Mccready
Hi! Consider setting Auri's answer as the main answer as makecert is deprecated. Link to the answer: https://mcmap.net/q/35905/-how-can-i-create-a-self-signed-cert-for-localhostDerbyshire
described process for win/osx here alfilatov.com/posts/how-to-create-self-signed-certificateLitch
For the googlers, please head up to https://mcmap.net/q/35904/-getting-chrome-to-accept-self-signed-localhost-certificate-closed. TL;DR: Use mkcert for a good certificate and installation on your OS.Verada
T
196

Since this question is tagged with IIS and I can't find a good answer on how to get a trusted certificate I will give my 2 cents about it:

First use the command from @AuriRahimzadeh in PowerShell as administrator:

New-SelfSignedCertificate -DnsName "localhost" -CertStoreLocation "cert:\LocalMachine\My" -NotAfter (Get-Date).AddYears(100)

Added Valid to 100 years so that the cert for localhost hopefully does not expire. You can use -NotAfter (Get-Date).AddMonths(24) for 24 months if you want that instead or any other value.

This is good but the certificate is not trusted and will result in the following error. It is because it is not installed in Trusted Root Certification Authorities.

enter image description here

Solve this by starting mmc.exe.

Then go to:

File -> Add or Remove Snap-ins -> Certificates -> Add -> Computer account -> Local computer. Click Finish.

Expand the Personal folder and you will see your localhost certificate:

enter image description here

Copy the certificate into Trusted Root Certification Authorities - Certificates folder.

The final step is to open Internet Information Services (IIS) Manager or simply inetmgr.exe. From there go to your site, select Bindings... and Add... or Edit.... Set https and select your certificate from the drop down.

enter image description here

Your certificate is now trusted:

enter image description here

Towardly answered 14/2, 2018 at 14:54 Comment(11)
This should be the accepted answer! It works! If you messed around with the localhost and trusted certificate. Be sure to remove all of the old localhost certificates (via mmc console and IIS (top managed server)Weasel
Thanks! There are so many SO answers and blog post on this topic, but very few talks about the certificate trust issues. Tip: Maybe you should explain why you don't use default SSL port 443? I guess it's because this port is often taken by some other process.Greenhouse
Really nice answer, and works well on IIS as 2020. Thanks a lot!Paramour
As soon as I refresh the Certificates folder the certificate gets removed.Oxeyed
On windows 11 and without IIS, this nearly worked. I needed to export and then re-import the certificate before I could get Edge/Brave to recognise it. Restarts of machine or browser etc did not achieve that. Once export/delete/import was done on the trusted cert, it worked.Agribusiness
@Agribusiness can you provide more detail on the export/delete/import? I upgraded to Windows 11 last week and since then I haven't been getting prompted for a CAC on my local application instance. I've tried creating new certs and adding them to the trusted root store as above, but that hasn't worked for me.Berne
If you don't want repeat all of these steps after 1 year you can use the "-NotAfter" option to create a certificate that will expire some years further. For example: New-SelfSignedCertificate -DnsName "localhost" -CertStoreLocation "cert:\LocalMachine\My" -NotAfter "31/12/2199"Wane
I am getting New-SelfSignedCertificate : CertEnroll::CX509Enrollment::_CreateRequest: Access is denied. 0x80070005 (WIN32: 5 ERROR_ACCESS_DENIED) At line:1 char:1 + New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -C ... when I try to create a certificateHopper
I run in admin mode and it worked but I am getting 0x80070520 error on selecting the certificate in domain bindings. The error basically says that the certificate is corrupted.Hopper
If you vote down please add a comment why. Hard to improve answers otherwiseTowardly
@Ogglas: This worked perfectly for localhost. Is there any way to do the same for local IP so that I can access it within our organization with https?Musselman
A
110

Although this post is post is tagged for Windows, it is relevant question on OS X that I have not seen answers for elsewhere. Here are steps to create a self-signed cert for localhost on OS X:

# Use 'localhost' for the 'Common name'
openssl req -x509 -sha256 -nodes -newkey rsa:2048 -days 365 -keyout localhost.key -out localhost.crt

# Add the cert to your keychain
open localhost.crt

In Keychain Access, double-click on this new localhost cert. Expand the arrow next to "Trust" and choose to "Always trust". Chrome and Safari should now trust this cert. For example, if you want to use this cert with node.js:

var options = {
    key: fs.readFileSync('/path/to/localhost.key').toString(),
    cert: fs.readFileSync('/path/to/localhost.crt').toString(),
    ciphers: 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384',
    honorCipherOrder: true,
    secureProtocol: 'TLSv1_2_method'
};

var server = require('https').createServer(options, app);
Accursed answered 23/8, 2015 at 17:28 Comment(8)
The first command, ssh-keygen, is unnecessary as the openssl command is also creating a new key (and overwriting the one created by ssh).Cancel
@FélixSaparelli Totally right. Missed that somehow. Editing the answer.Accursed
Also you can automate the process completely by adding -subj '/CN=localhost' to the openssl arguments.Cancel
To have OS X trust it from the command line instead of clicking around, you can do: sudo security add-trusted-cert -p ssl -d -r trustRoot -k ~/Library/Keychains/login.keychain localhost.crtOtti
Also relevant for linux. Thanks a lot.Placeman
I followed all these steps and I'm getting a ERR_SSL_VERSION_OR_CIPHER_MISMATCH in Chrome 60 and Safari 10.1.2 doesn't like it either.Restoration
Chrome: version 65 getting Certificate presented to the app has different CN (common name) than the domain of the request on my REST client. Does the common name need to include the port number? localhost:8443 or is it localhost alone?Dickey
If the browser still does not accept the certificate, add to the openssl command the -extension and -config parameters as Arjun Kava wrote in his reply.Barbette
P
61

You can use PowerShell to generate a self-signed certificate with the new-selfsignedcertificate cmdlet:

New-SelfSignedCertificate -DnsName "localhost" -CertStoreLocation "cert:\LocalMachine\My"

Note: makecert.exe is deprecated.

Cmdlet Reference: https://learn.microsoft.com/en-us/powershell/module/pki/new-selfsignedcertificate?view=windowsserver2022-ps

Pravit answered 24/5, 2017 at 17:5 Comment(6)
This should be the answer as of 2017.Derbyshire
For those who follow and don't know how to go about installing the resultant cert, follow the steps in this video, it worked for me! youtube.com/watch?v=y4uKPUFmSZ0Vacuum
where do the key and crt files get stored?Hereinto
@Hereinto with -KeyLocation flag you can specify location.Verbena
This answer is useful, but incomplete, because the certificate won't be trusted. See the other answer about adding it as a trusted authority.Fransen
New-SelfSignedCertificate -DnsName "localhost" -CertStoreLocation "cert:\LocalMachine\My" -KeyLocation "c:\users\mad\certs" generates no file in the specified directory.Adamsun
R
46

After spending a good amount of time on this issue I found whenever I followed suggestions of using IIS to make a self signed certificate, I found that the Issued To and Issued by was not correct. SelfSSL.exe was the key to solving this problem. The following website not only provided a step by step approach to making self signed certificates, but also solved the Issued To and Issued by problem. Here is the best solution I found for making self signed certificates. If you'd prefer to see the same tutorial in video form click here.

A sample use of SelfSSL would look something like the following:

SelfSSL /N:CN=YourWebsite.com /V:1000 /S:2

SelfSSL /? will provide a list of parameters with explanation.

Redblooded answered 25/7, 2013 at 1:51 Comment(4)
The article by RobBagby.com worked perfectly for me. Good find Henry.Animato
MEGA! That video has poor quality but has everything needed.Groscr
The link to robbagby site is dead. See my answer for 2 high quality youtube tutorials by CodeCowboyOrgGaye
Edited answer to link to Wayback archive of article on robbagby.com.Greta
H
23

If you are trying to create a self signed certificate that lets you go http://localhost/mysite Then here is a way to create it

makecert -r -n "CN=localhost" -b 01/01/2000 -e 01/01/2099 -eku 1.3.6.1.5.5.7.3.1 -sv localhost.pvk localhost.cer
cert2spc localhost.cer localhost.spc
pvk2pfx -pvk localhost.pvk -spc localhost.spc -pfx localhost.pfx

From http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/32bc5a61-1f7b-4545-a514-a11652f11200

Historic answered 30/4, 2012 at 1:17 Comment(7)
where did my certificate go :o its not in C:\Windows\system32Pneuma
By the way, the makecert.exe tool is used via the Visual Studio Command prompt for future readers. You could also use the the Internet Information Services (IIS) Resource Kit Tools and install SelfSSL 1.0. microsoft.com/downloads/en/…Ehr
While quick answers are great, they do not always help. "Certificate cannot be used as an SSL server certificate" is an error I see in IIS7. Op had also mentioned browser warnings & not "How do I create a cert"?Enabling
You can omit cert2spc step due parameter pvk2pfx -spc accepts both .spc and .cerLynwoodlynx
the eku is for code signing, if you want a SSL cert you need to use the eku 1.3.6.1.5.5.7.3.1. Persionally I do -eku 1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.3 which gives you Client Auth, Server Auth, and Code Signing.Sloe
@Pneuma Mine was in C:\Windows\SysWOW64Deepen
According with learn.microsoft.com/en-us/windows/win32/seccrypto/makecert "MakeCert is deprecated. To create self-signed certificates, use the Powershell Cmdlet New-SelfSignedCertificate." I used the command New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My ` -DnsName "testdomain.local" -Verbose` from tutorialspoint.com/…Elburt
P
10

I would recomment Pluralsight's tool for creating self-signed-certs: http://blog.pluralsight.com/selfcert-create-a-self-signed-certificate-interactively-gui-or-programmatically-in-net

Make your cert as a .pfx and import it into IIS. And add it as a trusted root cert authority.

Preterhuman answered 23/10, 2015 at 8:4 Comment(1)
After flapping around with trying all kinds of PowerShell "magic" and other stuff that just didn't work - Pluralsight's tool generated a working script for me in 30 seconds flat, and that includes the time it took to eat the pizza (+ download and extract the tool, I mean). As I'm still running Windows 7 on this old laptop - this was the perfect solution for me, thanks!Cakewalk
R
6

Fastest Way to generate localhost certificate.

openssl req -x509 -out localhost.crt -keyout localhost.key \
  -newkey rsa:2048 -nodes -sha256 \
  -subj '/CN=localhost' -extensions EXT -config <( \
   printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
Realty answered 20/5, 2021 at 6:13 Comment(1)
At line:3 char:53 + -subj '/CN=localhost' -extensions EXT -config <( \ + ~ Missing closing ')' in expression. Removing brackets doe snot work eitherHopper
U
3

Yes and no. Self signed certificates result in that warning message because the certificate was not signed by a trusted Certificate Authority. There are a few options that you can consider to remove this warning on your local machine. See the highest ranked answers to this question for details:

What do I need to do to get Internet Explorer 8 to accept a self signed certificate?

Hope this helps!


EDIT:

Sorry, I wasn't initially aware that you were constrained to localhost. You can attempt to follow the directions on the the link below to "Generate a Self Signed Certificate with the Correct Common Name."

http://www.sslshopper.com/article-how-to-create-a-self-signed-certificate-in-iis-7.html

Underbred answered 17/11, 2011 at 15:51 Comment(1)
No, the warning message is there because the URL (localhost) doesn't match the cert name, which is issued under the machine name. If I switch to mymachinename then I don't get the error. Unfortunately, I have to use localhost and not machine name for reasons that don't affect the question.Mccready
O
2

In a LAN (Local Area Network) we have a server computer, here named xhost running Windows 10, IIS is activated as WebServer. We must access this computer via Browser like Google Chrome not only from localhost through https://localhost/ from server itsself, but also from other hosts in the LAN with URL https://xhost/ :


https://localhost/
https://xhost/
https://xhost.local/
...

With this manner of accessing, we have not a fully-qualified domain name, but only local computer name xhost here.

Or from WAN:


https://dev.example.org/
...

You shall replace xhost by your real local computer name.

None of above solutions may satisfy us. After days of try, we have adopted the solution openssl.exe. We use 2 certificates - a CA (self certified Authority certificate) RootCA.crt and xhost.crt certified by the former. We use PowerShell.

1. Create and change to a safe directory:

cd C:\users\so\crt

2. Generate RootCA.pem, RootCA.key & RootCA.crt as self-certified Certification Authority:


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

3. make request for certification: xhost.key, xhost.csr:

C: Country
ST: State
L: locality (city)
O: Organization Name
Organization Unit
CN: Common Name

    

openssl req -new -nodes -newkey rsa:2048 -keyout xhost.key -out xhost.csr -subj "/C=ZA/ST=FREE STATE/L=Golden Gate Highlands National Park/O=WWF4ME/OU=xhost.home/CN=xhost.local"

4. get xhost.crt certified by RootCA.pem:


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

with extfile domains.ext file defining many secured ways of accessing the server website:

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = xhost
DNS.3 = xhost.local
DNS.4 = dev.example.org
DNS.5 = 192.168.1.2

5. Make xhost.pfx PKCS #12,

combinig both private xhost.key and certificate xhost.crt, permitting to import into iis. This step asks for password, please let it empty by pressing [RETURN] key (without password):


openssl pkcs12 -export -out xhost.pfx -inkey xhost.key -in xhost.crt

6. import xhost.pfx in iis10

installed in xhost computer (here localhost). and Restart IIS service.

IIS10 Gestionnaire des services Internet (IIS) (%windir%\system32\inetsrv\InetMgr.exe)

enter image description here

enter image description here

7. Bind ssl with xhost.local certificate on port 443.

enter image description here

Restart IIS Service.

8. Import RootCA.crt into Trusted Root Certification Authorities

via Google Chrome in any computer that will access the website https://xhost/.

\Google Chrome/…/Settings /[Advanced]/Privacy and Security/Security/Manage certificates

Import RootCA.crt

enter image description here

The browser will show this valid certificate tree:


RootCA-CA
  |_____ xhost.local

enter image description here

No Certificate Error will appear through LAN, even through WAN by https://dev.example.org.

enter image description here

Here is the whole Powershell Script socrt.ps1 file to generate all required certificate files from the naught:


#
# Generate:
#   RootCA.pem, RootCA.key RootCA.crt
#
#   xhost.key xhost.csr xhost.crt
#   xhost.pfx
#
# created  15-EEC-2020
# modified 15-DEC-2020
#
#
# change to a safe directory:
#

cd C:\users\so\crt

#
# Generate RootCA.pem, RootCA.key & RootCA.crt as Certification Authority:
#
openssl req -x509 -nodes -new -sha256 -days 10240 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=ZA/CN=RootCA-CA"
openssl x509 -outform pem -in RootCA.pem -out RootCA.crt

#
# get RootCA.pfx: permitting to import into iis10: not required.
#
#openssl pkcs12 -export -out RootCA.pfx -inkey RootCA.key -in RootCA.crt

#
# get xhost.key xhost.csr:
#   C: Country
#   ST: State
#   L: locality (city)
#   O: Organization Name
#   OU: Organization Unit
#   CN: Common Name
#
openssl req -new -nodes -newkey rsa:2048 -keyout xhost.key -out xhost.csr -subj "/C=ZA/ST=FREE STATE/L=Golden Gate Highlands National Park/O=WWF4ME/OU=xhost.home/CN=xhost.local"

#
# get xhost.crt certified by RootCA.pem:
# to show content:
#   openssl x509 -in xhost.crt -noout -text
#
openssl x509 -req -sha256 -days 1024 -in xhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out xhost.crt

#
# get xhost.pfx, permitting to import into iis:
#
openssl pkcs12 -export -out xhost.pfx -inkey xhost.key -in xhost.crt

#
# import xhost.pfx in iis10 installed in xhost computer (here localhost).
#

To install openSSL for Windows, please visit https://slproweb.com/products/Win32OpenSSL.html

Obligate answered 15/12, 2020 at 22:8 Comment(0)
A
1

you could try mkcert.

macos: brew install mkcert

Adinaadine answered 22/5, 2020 at 8:57 Comment(0)
A
1

Here's what I did to get a valid certificate for localhost on Windows:

  1. Download mkcert executable (https://github.com/FiloSottile/mkcert/releases) and rename it to mkcert.exe
  2. Run "mkcert -install"
  3. Open Windows certificate manager (certmgr.msc)
  4. Right click on "Trusted Root Certification Authorities" -> Import
  5. Import Root cert (rootCA.pem) from C:\Users[username]\AppData\Local\mkcert\
  6. Create a *.p12 certificate for specified domain(s): "mkcert -pkcs12 [name1] [name2]"
  7. Rename *.p12 certificate into *.pfx
  8. In IIS -> Server Certificates -> Import (pfx) in "Personal" group [default password: "changeit"]
  9. Assign certificate to Default Web Site (binding -> https (443) -> modify -> SSL certificate)
Amalamalbena answered 2/3, 2022 at 13:11 Comment(0)
D
1

if you want it quick and easy, run this

        var enabled   = false;
        if(enabled){
              window.onload   = e=>{
                    var today       = new Date();
                    var one_year    = new Date();
                    one_year.setFullYear(one_year.getFullYear()+1);
                    
                    var config      = {};
                    
                    config.from     = today;
                    config.to       = one_year;
                    
                    config.dns      = ['localhost'];
                    config.ip       = ['127.0.0.1','127.0.0.2'];
                    
                    config.rdn      = {};
                    
                    config.rdn.cn   = 'localhost test certificate';
                    config.rdn.o    = 'Test';
                    config.rdn.ou   = 'test';
                    config.rdn.l    = 'Blacksburg';
                    config.rdn.st   = 'Virginia';
                    config.rdn.c    = 'US';
                    
                    generate_certificate(config);
              };
        }

        
        $('#tab-config').onclick                                    = e=>show('config');
        $('#tab-cert').onclick                                      = e=>show('cert');
        
        $('#config-btns [value="generate certificate"]').onclick    = read;
        $('#config-btns [value=clear]').onclick                     = clear;
        $('#config-btns [value=localhost]').onclick                 = localhost;
        
        var rdns                                                    = ['cn','o','ou','l','st','c'];
        var list                                                    = {};
        list.dns                                                    = $('#dns-list');
        list.ip                                                     = $('#ip-list');
        var item                                                    = {};
        item.dns                                                    = $(list.dns,'.item');
        item.ip                                                     = $(list.ip,'.item');
        
        $('#dns-root [value=add]').onclick                          = e=>create('dns');
        $('#ip-root [value=add]').onclick                           = e=>create('ip');
            
        $('#from').value                                            = date();
        $('#to').value                                              = date(true);


        localhost();


        function localhost(){
              clear(true);
              $('#cn').value    = 'localhost test certificate';
              ['localhost'].forEach(value=>create('dns',value));
              ['127.0.0.1','127.0.0.2'].forEach(value=>create('ip',value))
        }
        
        function $(root,sel){
              if(!sel){sel=root;root=document};
              return root.querySelector(sel);
        }
        
        function create(type,value){
              var nitem                           = item[type].cloneNode(true);
              $(nitem,'.rem').onclick             = e=>nitem.remove();
              if(value)$(nitem,'.value').value    = value;
              list[type].append(nitem);
        }
        
        function clear(mode){
              rdns.forEach(name=>$('#'+name).value    = '');
              list.dns.replaceChildren();
              if(!mode)create('dns');
              list.ip.replaceChildren();
              if(!mode)create('ip');
        }
        
        function date(adj){
              var now       = new Date();
              var offset    = now.getTimezoneOffset()*60000;
              var local     = new Date(now.getTime()-offset);
              if(adj){
                    local.setFullYear(local.getFullYear()+1);
              }
              var date      = local.toISOString().substring(0,16);
              return date;
        }
        
        function read(){
              var config    = {};
              config.rdn    = {};
              rdns.forEach(name=>config.rdn[name]=$('#'+name).value);
              var arr       = type=>[...list[type].querySelectorAll('.item')].map(node=>$(node,'.value').value).filter(v=>v);
              config.dns    = arr('dns');
              config.ip     = arr('ip');
              config.from   = new Date($('#from').value);
              config.to     = new Date($('#to').value);
              
              generate_certificate(config);
        };
        
        function generate_certificate(config){
          
              var {key,cert,forge_cert}       = generateCertificate(config);
              
              show('cert');
              
              $('#key-copy').onclick          = e=>copy(key,$('#key'));
              $('#key-download').href        = window.URL.createObjectURL(new Blob([key]));
              $('#key-download').download    = 'private-key.pem';
              $('#key-download').onclick    = e=>download('private-key.pem',key);
              
              $('#x509-copy').onclick         = e=>copy(cert,$('#x509'));
              $('#x509-download').href        = window.URL.createObjectURL(new Blob([cert]));
              $('#x509-download').download    ='server-cert.pem';
              $('#x509-download').onclick   = e=>download('server-cert.pem',cert);
              
              $('#key').value                 = key
              $('#x509').value                = cert;
                            
        };
        
        function show(name){
              if(name==='config'){
                    $('#tab-config').classList.remove('inactive');
                    $('#tab-config').classList.add('active');
                    $('#config').style.display    = '';
                    $('#tab-cert').classList.remove('active');
                    $('#tab-cert').classList.add('inactive');
                    $('#cert').style.display      = 'none';
              }else{
                    $('#tab-config').classList.remove('active');
                    $('#tab-config').classList.add('inactive');
                    $('#config').style.display    = 'none';
                    $('#tab-cert').classList.remove('inactive');
                    $('#tab-cert').classList.add('active');
                    $('#cert').style.display      = '';
              }
        }
        
        function download(filename,txt){
              var blob      = new Blob([txt]);
              var a         = $('a');
              a.download    = filename;
              a.href        = window.URL.createObjectURL(blob);
              a.click();
        }
        
        async function copy(txt){
            try {
              await navigator.clipboard.writeText(txt);
            }
            catch (error) {
              alert(error.message);
            }
        }
        
        function copy(text,textarea){
              if (!navigator.clipboard) {
                fallback();
                return;
              }
              navigator.clipboard.writeText(text).then(function() {
                console.log('Async: Copying to clipboard was successful!');
              }, function(err) {
                fallback();
              });
              
              function fallback(text) {
                
                textarea.focus();
                textarea.select();
                try{
                      var successful = document.execCommand('copy');
                      if(!successful){
                        alert('failed to copy');
                      }
                } 
                catch(err){
                      alert('unable to copy', err);
                }
              
                document.body.removeChild(textArea);
              }
          
        }
              html,body {
                margin:0;
              }
              section {
                font-family:arial;
                width:100%;
                height:200px;
                position:relative;
              }
              input {
                box-sizing:border-box;
                font-size:16px;
                font-weight:bold;
                padding:5px 10px;
              }
              
              #tabs {
                display:flex;
                cursor:pointer;
                margin-bottom:10px;
                text-align:center;
              }
              .tab {
                padding:5px 0;
                flex:1;
              }
              .active {
                background:lightyellow;
                border:1px solid lightblue;
              }
              
              .inactive {
                background:lightgray;
                border:1px solid dimgray;
              }

              #view {
                position:absolute;
                inset:35px 0 0 0;
              }
              
              #config {
                position:absolute;
                inset:0 0 0 0;
              }
              #config-btns input {
                margin-right:20px;
              }

              #config-body {
                overflow:auto;
                position:absolute;
                inset:30px 0 0 0;
                padding:10px;
              }
              
              .hdr {
                height:25px;
                margin:10px auto;
                background-color:whitesmoke;
                padding:5px 10px;
              }
              .hdr input{
                margin-left:20px;
              }
              
              
              #rdns {
                display:grid;
                grid-template-columns:auto 1fr;
                gap:5px 20px;
              }
              #rdns div:nth-of-type(odd) {
                white-space:nowrap;
                overflow:hidden;
                max-width:200px;
              }
              #rdns input {
                width:100%;
                box-sizing:border-box;
              }
                
              .item {
                display:flex;
                align-items:center;
              }
              .rem {
                margin-right:10px;
                color:red;
              }
              .item div:nth-of-type(2) {
                flex:1;
              }
              .value {
                width:100%
              }
              
              #dates {
                display:grid;
                grid-template-columns:100px auto;
                gap:5px 20px;
              }
              
              #cert {
                padding:0px 10px;
              }
              
              #cert > div {
                margin-bottom:10px;
              }
              
              #cert input {
                margin:auto 10px;
              }
              
              #cert-body {
                position:absolute;
                inset:80px 10px 0 10px;
                overflow:auto;
              }
              
              #cert-body {
                display:flex;
              }
              textarea {
                flex:1;
              }
              
              a {
                border-width:2px;
                border-style:inset;
                border-color:dimgray;
                background:buttonface;          
                font-weight:bold;
                font-size:12px;
                border-radius:3px;
                padding:5px 10px;
              }
        <section>
        
              <div id=tabs>
                    <div id=tab-config class='tab active'>config</div>
                    <div id=tab-cert class='tab inactive'>certificate</div>
              </div>
              
              <div id=view>
              
                    <div id=config>
                          <div id=config-btns><input type=button value=clear><input type=button value=localhost><input type=button value='generate certificate'></div>
                          <div id=config-body>
                                <div id=rdns-root>
                                      <div class=hdr>Relative Distinguished Names</div>
                                      <div id=rdns>
                                            <div>CommonName (CN) </div><div><input id=cn></div>
                                            <div>Organization (O) </div><div><input id=o></div>
                                            <div>OrganizationalUnit (OU) </div><div><input id=ou></div>
                                            <div>Locality (L) </div><div><input id=l></div>
                                            <div>StateOrProvince (ST) </div><div><input id=st></div>
                                            <div>CountryName (C) </div><div><input id=c></div>
                                      </div>
                                </div>
                                <div id=dns-root>
                                      <div class=hdr>dns names (example.com) <input type=button value=add></div>
                                      <div id=dns-list>
                                            <div class=item><input type=button value=x class=rem><div><input id=dns class=value></div></div>
                                      </div>
                                </div>
                                <div id=ip-root>
                                      <div class=hdr>ips (127.0.0.1) <input type=button value=add></div>
                                      <div id=ip-list>
                                            <div class=item><input type=button value=x class=rem><div><input id=ip class=value></div></div>
                                      </div>
                                </div>
                                <div id=dates-root>
                                      <div class=hdr>dates</div>
                                      <div id=dates>
                                            <div>from</div><input id=from type=datetime-local>
                                            <div>to</div><input id=to type=datetime-local>
                                      </div>
                                </div>
                          </div>
                    </div>
                    
                    <div id=cert style='display:none'>
                          <div>private key (pem) <input id=key-copy type=button value='copy to clipboard'><a id=key-download>download, right-click : save link as</a></div>
                          <div>x509 cert (pem) <input id=x509-copy type=button value='copy to clipboard'><a id=x509-download>download, right-click : save link as</a></div>
                          <div id=cert-body>
                                <textarea id=key></textarea>
                                <textarea id=x509></textarea>
                          </div>
                    </div>
                    
              </div>
            
        </section>


<script type="module">

        import nodeForge from 'https://cdn.jsdelivr.net/npm/node-forge/+esm';
        var pki                   = nodeForge.pki;
        
        window.generateCertificate=function(config){
          
              var keys                  = pki.rsa.generateKeyPair(2048);
              var cert                  = pki.createCertificate();
              
              cert.publicKey            = keys.publicKey;
              
              cert.serialNumber         = '01';
              cert.validity.notBefore   = config.from;
              cert.validity.notAfter    = config.to;
              
              var attrs   = [];
              rdns.forEach(name=>{if(config.rdn[name])attrs.push({shortName:name.toUpperCase(),value:config.rdn[name]})});

              cert.setSubject(attrs);
              cert.setIssuer(attrs);
      
              cert.setExtensions([
                    {
                          name                : 'basicConstraints',
                          cA                  : false
                    },
                    {
                          name                : 'keyUsage',
                          keyCertSign         : true,
                          digitalSignature    : true,
                          nonRepudiation      : true,
                          keyEncipherment     : true,
                          dataEncipherment    : true
                    },
                    {
                          name                : 'extKeyUsage',
                          serverAuth          : true,
                          clientAuth          : true,
                          codeSigning         : true,
                          emailProtection     : true,
                          timeStamping        : true
                    },
                    {
                          name                : 'nsCertType',
                          client              : true,
                          server              : true,
                          email               : true,
                          objsign             : true,
                          sslCA               : true,
                          emailCA             : true,
                          objCA               : true
                    },
                    {
                          name                : 'subjectAltName',
                          altNames            : [config.dns.map(dns=>{return {type:2,value:dns}}),config.ip.map(ip=>{return {type:7,ip}})].flat()
                    },
                    {
                          name                : 'subjectKeyIdentifier'
                    }
              ]);
              
              cert.sign(keys.privateKey);
              
              var key           = pki.privateKeyToPem(keys.privateKey);
              var cert          = pki.certificateToPem(cert);
              var forge_cert    = pki.certificateFromPem(cert);

              return {key,cert,forge_cert};
              
        };
</script>

this will generate you a self-signed x509 certificate with private key right now, here in the browser

set your distinguished names, dns names, ip addresses and certificate validity date ranges in the config tab using the simple ui and hit generate certificate

you can verify the certificate online certificate checker / decoder

if you want your certificate to be trusted automatically, you'd have to install it into the trusted root store, following any of the many examples in the other answers to this question

note also you can take this code away and run it for yourself, you'll need an internet connection it uses node-forge library to generate the certificate, or bookmark the page

if you want to follow up on this, discuss and other cool stuff come join us in the stackoverflow javascript chat

Dorwin answered 20/3 at 9:45 Comment(0)
E
0

If you are using Visual Studio, there is an easy way to setup and enable SSL using IIS Express explained here

Exposed answered 29/12, 2019 at 23:48 Comment(0)
H
0

Solution for Windows 10

None of the above worked for me but this one:

1. Follow these steps

$cert = New-SelfSignedCertificate -Subject local.YourDomain -DnsName local.yourdomain.co.uk

then

Format-List -Property *

or steps under Creating A Certificate With a Single Subject here: https://adamtheautomator.com/new-selfsignedcertificate/

You can also try SAN (Creating A Subject Alternative Name (SAN) Certificate).

2. Open mmc

Open Windows search and type mmc

then follow these steps:

Open File > Add/Remove Snap-in, select Certificates and click Add. Select Computer account, click Next and then Finish.

3. Copy certificate from Personal to Trusted

Expand Personal under Certificates in mmc

Copy your new certificate from Personal to Trusted Root Certification Authorities

4. Select the new certificate for your domain binding in IIS

5. Restart the domain/ site

Hopper answered 13/12, 2022 at 12:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.