192

Trying to follow various instructions on creating a self-signed cert for use with localhost, Most of the instructions seem to be for IIS, but I'm trying to use Nodejs/Express. None of them work properly because while the cert gets installed, it is not trusted. here's what I've tried that fails:

Can someone offer a workflow that can do this? I can get a cert installed, but I can't get the cert to be trusted in either chrome (v32) or IE (v10).

EDIT: it was suggested in comments that the problem is no trusted cert-root. I installed the cert via IE but it's still not being trusted.

Community
  • 1
  • 1
JasonS
  • 7,443
  • 5
  • 41
  • 61
  • None of the self signed certificates can be made trusted for web browsers. They are not signed by trusted signing authorities. –  Jan 28 '14 at 06:25
  • 1
    that's not true: you can install a root certificate to get your self-signed cert trusted. however I can't seem to do this properly. I read that you can install the cert chain in IE (not in chrome), so I tried that but it's still not being recognized. I don't know if it's because localhost is special or if the self-signed cert is just not correct. – JasonS Jan 28 '14 at 06:29
  • 3
    I never got a self-signed cert working with browsers like Chrome. Here is my workaround: I created a DNS entry for local.MYDOMAIN.com pointing to 127.0.0.1 (localhost) and then just use my production cert. This has the added benefit of making sure there are no problems with your production cert chain, etc. – JasonS Jul 12 '16 at 17:37

17 Answers17

173

The answers above were partial. I've spent so much time getting this working, it's insane. Note to my future self, here is what you need to do:

I'm working on Windows 10, with Chrome 65. Firefox is behaving nicely - just confirm localhost as a security exception and it will work. Chrome doesn't:

Step 1. in your backend, create a folder called security. we will work inside it.

Step 2. create a request config file named req.cnf with the following content (credit goes to: @Anshul)

req.cnf :

[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = Country initials like US, RO, GE
ST = State
L = Location
O = Organization Name
OU = Organizational Unit 
CN = www.localhost.com
[v3_req]
keyUsage = critical, digitalSignature, keyAgreement
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = www.localhost.com
DNS.2 = localhost.com
DNS.3 = localhost

An explanation of this fields is here.

Step 3. navigate to the security folder in the terminal and type the following command :

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout cert.key -out cert.pem -config req.cnf -sha256

Step 4. then outside of security folder, in your express app do something like this: (credit goes to @Diego Mello)

backend 
 /security
 /server.js

server.js:

const express = require('express')
const app = express()
const https = require('https')
const fs = require('fs')
const port = 3000

app.get('/', (req, res) => {
    res.send("IT'S WORKING!")
})

const httpsOptions = {
    key: fs.readFileSync('./security/cert.key'),
    cert: fs.readFileSync('./security/cert.pem')
}
const server = https.createServer(httpsOptions, app)
    .listen(port, () => {
        console.log('server running at ' + port)
    })

Step 5. start the server, node server.js, and go to https://localhost:3000.

At this point we have the server setup. But the browser should show a warning message.

We need to register our self-signed certificate, as a CA trusted Certificate Authority, in the chrome/windows certificates store. (chrome also saves this in windows,)

Step 6. open Dev Tools in chrome, go to Security panel, then click on View Certificate. enter image description here

Step 7. go to Details panel, click Copy File, then when the Certificate Export Wizard appears, click Next as below:

go to details - copy file - next on export wizard

Step 8. leave DER encoding, click next, choose Browse, put it on a easy to access folder like Desktop, and name the certificate localhost.cer, then click Save and then Finish.. You should be able to see your certificate on Desktop.

Step 9. Open chrome://settings/ by inserting it in the url box. Down below, click on Advanced / Advanced Options, then scroll down to find Manage Certificates.

choose manage certificates

Step 10. Go to Trusted Root Certification Authorities panel, and click import.

Go to Trusted Root Certification Authorities panel, and click import

We will import the localhost.cer certificate we just finished exporting in step 8.

Step 11. click browse, find the localhost.cer, leave the default values click next a bunch of times - until this warning appears, click yes.

confirm security exception

Step 12. close everything, and restart chrome. Then, when going to https://localhost:3000 you should see: gotta love the green

AIon
  • 12,521
  • 10
  • 47
  • 73
  • Hi, when I finish all the steps I open `https://localhost:3000` and Chrome is stuck on loading. Anyone can tell what might be the reason? – co.zohar Oct 04 '18 at 13:24
  • @co.zohar any message in the console? Press `crl+shift+i` or `F12` to open the console. – AIon Oct 04 '18 at 17:45
  • 1
    If you're doing this for an address on a network I found that setting up the certificate DNS to a hostname such as: `DNS.1 = server.local` Then on the connecting machine update the HOSTS file to point the server IP address to the hostname, for example: `192.168.0.50 server.local` This will allow the certificate and the address to match up and validate the certificate. – roskelld Oct 05 '18 at 18:20
  • @AIon the console doesn't show anything. The page just shows: "Waiting for localhost...". Did you configure anything in the hosts file? – co.zohar Oct 07 '18 at 07:51
  • @co.zohar "Waiting for localhost..." indeed seems like an DNS resolution problem. I have an uncomented line in the hosts file: `127.0.0.1 localhost #transitCalculator` Not sure who put it here. `#` means a commented line. The line i have typed here is uncomented. Please check you have aprox the same configuration there. – AIon Oct 07 '18 at 08:59
  • @AIon Hi, I didn't have to have any row in the hosts file. Your initial solution worked perfectly. I didn't include the "app.get('/') and that's why it was waiting for localhost forever. Thank you – co.zohar Oct 07 '18 at 11:35
  • @Alon it's unclear which of the fields in req.cnf need to be changed – TKoL Feb 26 '19 at 10:21
  • @Alon nevermind I think I got it. But what if we want it, instead of being localhost, to be an ip on the network? For example if I was running my node server on 192.168.1.10 and wanted other computers on the network to access it via https, how could i change your advice and have it still work? – TKoL Feb 26 '19 at 10:36
  • 1
    I found a semi-answer to my own question: if you change CN and DNS.1 to something like "local.com" for example, and in each computer that needs access to the server, change the etc/hosts file to point local.com to the ip of the server, this works. – TKoL Feb 26 '19 at 11:38
  • 3
    Step 2 is creating issue in window. 14148:error:0D07A097:asn1 encoding routines:ASN1_mbstring_ncopy:string too long:.\crypto\asn1\a_mbstr.c:158:maxsize=2 – Hermenpreet Singh Jul 19 '20 at 18:08
  • @Hermenpreet Singh not sure what you mean. step 2 is only about creating that file and pasting that content inside it. Is not about validating that file content. But check this for what looks like a simmilar issue: https://github.com/certbot/certbot/issues/1915 – AIon Aug 07 '20 at 20:27
  • 2
    @HermenpreetSingh Its a problem with the country initials, you probably just didn't change the line in the req.cnf `C = Country initials like US, RO, GE`, it should just be something like `C = US` – sme Sep 21 '20 at 14:29
  • In step 3 I have this error: `Error making certificate request 34050000:error:06800097:asn1 encoding routines:ASN1_mbstring_ncopy:string too long:crypto\asn1\a_mbstr.c:106:maxsize=2` – El7or Jul 22 '22 at 13:11
147

Shortest way. Tested on MacOS, but may work similarly on other OS.

Generate pem

> openssl req -x509 -newkey rsa:2048 -keyout keytmp.pem -out cert.pem -days 365

> openssl rsa -in keytmp.pem -out key.pem

Your express server

const express = require('express')
const app = express()
const https = require('https')
const fs = require('fs')
const port = 3000

app.get('/', (req, res) => {
  res.send('WORKING!')
})

const httpsOptions = {
  key: fs.readFileSync('./key.pem'),
  cert: fs.readFileSync('./cert.pem')
}
const server = https.createServer(httpsOptions, app).listen(port, () => {
  console.log('server running at ' + port)
})
  • Open https://localhost:3000 in Google Chrome and you'll see that it's not secure. Yet!
  • In Developer Tools > Security > View Certificate: Drag image to your desktop and double click it.
  • Click 'Add'
  • Find it in Keychain Access and double click it
  • Expand 'Trust' and change 'When using this certificate' to 'Always trust'.
  • You may be prompted to authenticate.
  • Restart your server.
  • Refresh your browser.
  • Enjoy! :)
Loren
  • 13,903
  • 8
  • 48
  • 79
Diego Mello
  • 5,220
  • 3
  • 17
  • 21
  • Beautiful! This worked! I'd like to addition: Install OpenSSL from here: https://indy.fulgan.com/SSL/?C=M;O=A. Get the .cnf file from here: and then, configure it from here: https://gist.githubusercontent.com/pandurang90/dbe6a67339747ef5bacf/raw/ceb8bc0b30e206abaf9afdc030a7d24bc272b864/openssl.cnf and configure openSSL from here: https://stackoverflow.com/questions/7360602/openssl-and-error-in-reading-openssl-conf-file – Jose A Oct 10 '17 at 00:03
  • 2
    I'd like to add that for Chrome 58+, you're going to receive an error "Subject Alternative Name missing".https://stackoverflow.com/a/42917227/1057052. Check the answers below for more help: https://stackoverflow.com/a/43666288/1057052, https://stackoverflow.com/a/44398368/1057052 – Jose A Oct 10 '17 at 00:33
  • 19
    `Drag image to your desktop and double click it` -> i can't drag anything to my desktop, is not draggable.. What `image` are you talking about ore exactly? – AIon Nov 12 '17 at 11:48
  • 11
    To overcome "Subject Alternative Name missing" in Chrome, you could do `openssl req -newkey rsa:2048 -x509 -nodes -keyout keytmp.pem -new -out cert.pem -subj /CN=localhost -reqexts SAN -extensions SAN -config <(cat /System/Library/OpenSSL/openssl.cnf <(printf '[SAN]\nsubjectAltName=DNS:localhost')) -sha256 -days 3650` instead of the first line you suggested. And also this one will ask less questions in the process... – Michael Litvin Feb 07 '18 at 13:00
  • @AIon, this is only for MacOS, on Windows it's probably much more complicated ;) – Michael Litvin Feb 07 '18 at 13:01
  • Amazing, thanks!!! You'll also need to add to the `httpsOptions` `passphrase: 'XXXX'` – Belfield Jun 04 '18 at 15:50
  • I tried this exact exercise on Windows 10 OS and it worked. Thanks! – markreyes Feb 25 '19 at 17:58
  • this only works for safari and chrome, firefox still won't play. – rx2347 Jun 18 '20 at 20:56
  • for anyone looking to what cryptic drag and drop means find an answer here https://stackoverflow.com/questions/25940396/how-to-export-certificate-from-chrome-on-a-mac – Ren Jun 26 '22 at 11:44
77

You can try openSSL to generate certificates. Take a look at this.

You are going to need a .key and .crt file to add HTTPS to node JS express server. Once you generate this, use this code to add HTTPS to server.

var https = require('https');
var fs = require('fs');
var express = require('express');

var options = {
    key: fs.readFileSync('/etc/apache2/ssl/server.key'),
    cert: fs.readFileSync('/etc/apache2/ssl/server.crt'),
    requestCert: false,
    rejectUnauthorized: false
};


var app = express();

var server = https.createServer(options, app).listen(3000, function(){
    console.log("server started at port 3000");
});

This is working fine in my local machine as well as the server where I have deployed this. The one I have in server was bought from goDaddy but localhost had a self signed certificate.

However, every browser threw an error saying connection is not trusted, do you want to continue. After I click continue, it worked fine.

If anyone has ever bypassed this error with self signed certificate, please enlighten.

Mars Robertson
  • 12,673
  • 11
  • 68
  • 89
  • 11
    Your certificate is still not trusted, so you have the same problem I'm describing. I need it to be trusted to test/debug a webservice properly. – JasonS Jan 28 '14 at 06:38
  • 1
    So you want this certificate to be trusted only in your local machine and not in the network? –  Jan 28 '14 at 06:46
  • yeah, my dev environment is running on a single machine, and of course the "localhost" domain is only available locally :) – JasonS Jan 28 '14 at 12:37
  • does it still give the warning if you add the certificate to the browsers certificate list? – Binvention Feb 03 '16 at 03:35
  • 1
    the link at the top of the answer recomends 1024 bit 3DES encryption, which is way outdated. Better to use `openssl genrsa -out key.pem 2048` for a better key. – steampowered Aug 09 '16 at 17:55
  • 3
    Your certificate is still not trusted. – Diego Mello Feb 17 '17 at 10:55
  • As far as getting a certificate goes - this is probably better than using some untrusted self signed cert (and equally as free) https://letsencrypt.org/ – e_m0ney Mar 07 '17 at 02:26
  • Then, in Chrome, go to chrome://flags and activate "Allow invalid certificates for resources loaded from localhost." – Laurent Debricon Oct 03 '17 at 15:52
  • This should not be the accepted answer (yet). Note that some things require a green bar. E.g. if your website is also a progressive web ap (pwa), TLS is mandatory. For chrome 58+ to trust the certificate properly, you also need to become/create a CA (Certificate Authority). I found this resource quite usefull: https://ram.k0a1a.net/self-signed_https_cert_after_chrome_58 – Jos Dec 13 '17 at 10:41
  • 2
    the express code above works, utilising https://github.com/FiloSottile/mkcert (instead of openSSL) to create a local CA / trusted cert. Green bars all the way. – som Jan 07 '19 at 22:22
  • You just got the same http page but only the UI showing https, this is not correct, unsecure and still not working, can't understand why so many upvotes from people not checking thoroughly and (I guess) forget to remove their upvote only so people wont get confused thinking this is a viable answer, – clusterBuddy Mar 23 '20 at 13:09
29

Mkcert from @FiloSottile makes this process infinitely simpler:

  1. Install mkcert, there are instructions for macOS/Windows/Linux
  2. mkcert -install to create a local CA
  3. mkcert localhost 127.0.0.1 ::1 to create a trusted cert for localhost in the current directory
  4. You're using node (which doesn't use the system root store), so you need to specify the CA explicitly in an environment variable, e.g: export NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem"
  5. Finally run your express server using the setup described in various other answers (e.g. below)
  6. boom. localhost's swimming in green.

Basic node setup:

const https = require('https');
const fs = require('fs');
const express = require('express');

const app = express();    
const server = https.createServer({
    key: fs.readFileSync('/XXX/localhost+2-key.pem'), // where's me key?
    cert: fs.readFileSync('/XXX/localhost+2.pem'), // where's me cert?
    requestCert: false,
    rejectUnauthorized: false,
}, app).listen(10443); // get creative
som
  • 2,023
  • 30
  • 37
  • Works greatly! With this approach we don't need to register our self-signed certificate, as a CA trusted Certificate Authority, in the chrome/windows certificates store. As mentioned in other answers. – zaheer May 28 '19 at 19:03
  • Can I run this on pipelines ? here is a reference for my question https://stackoverflow.com/questions/71850480/express-https-azure-pipelines-secret-variable – Ibra Apr 13 '22 at 21:27
  • 1
    @Ibra there seems to be some discussion around pipelines usage on the [mkcert github repo](https://github.com/FiloSottile/mkcert/issues?q=azure) so assume it's possible .. but keep in mind mkcert isn't intended for production use – som Apr 14 '22 at 01:34
13

How to generate an SSL certificate for localhost: link

openssl genrsa -des3 -out server.key 1024

you need to enter a password here which you need to retype in the following steps

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

when asked "Common Name" type in: localhost

openssl x509 -req -days 1024 -in server.csr -signkey server.key -out server.crt
fuma
  • 5,067
  • 4
  • 35
  • 39
  • 1
    This is the solution ive scoured the internet for over the past 2 hours. For anyone in ubuntu move the `cp server.crt /usr/local/share/ca-certificates/.` and run `sudo update-ca-certificates` Then localhost https requests work under NodeJS 8+. Id also increase `1024 to 2048` – Salyangoz Sep 26 '18 at 04:05
7

Some of the answers posted have pieces that were very useful to me to overcome this problem too. However, I was also interested in the minimum number of steps and, ideally, avoiding OpenSSL (on Windows 10).

So, one critical piece from the answers (credit: @TroyWorks) is that you need to edit your HOSTS file to create a fictitious server, and map that to 127.0.0.1. This assumes you are going to be doing local development.

In my case, I was using the SS certificate to secure a websocket in NodeJS, and that socket was being connected to programmatically (as opposed to via browser). So for me, it was critical that the certificate be accepted without warnings or errors, and the critical piece there was to get the cert created with a proper CN (and of course accept the cert into Trusted Authorities, as described elsewhere in the answers). Using IIS to create a self-signed cert won't create the proper CN, so I discovered the following simple command using Powershell:

New-SelfSignedCertificate -DnsName "gandalf.dummy.dev" -FriendlyName "gandalf" -CertStoreLocation "cert:\LocalMachine\My"

This has to be run in the PS Admin console, but it simply works, and puts the cert into the "Personal" section of the LocalMachine certificate store. You can verify it got created by executing:

ls cert:\LocalMachine\My 

To trust it, simply copy this and paste into "Trusted Root Certification Authorities" using Certificate Manager (making sure you are looking at the Local Machine certificates, not Current User!).

If you bind to this certificate in IIS, you should be able to hit https://gandalf.dummy.dev/ and get a secure connection without any warnings.

The final piece, using this in NodeJS, is described above and in other SO answers, so I'll only add that on Windows, it is easier to work with a pfx file that combines the cert and private key. You can export a pfx easily from the Certificate Manager, but it does affect how you use it in NodeJS. When instantiating a Server using the 'https' module, the options you would use (instead of 'key' and 'cert') would be 'pfx' and 'passphrase', as in:

var https = require('https');
var options = { 
    pfx: fs.readFileSync('mypfxfile'), 
    passphrase: 'foo' 
};
var server = https.createServer(options);
tomo
  • 1,492
  • 13
  • 13
6

Here's what's working for me

on windows

1) Add this to your %WINDIR%\System32\drivers\etc\hosts file: 127.0.0.1 localdev.YOURSITE.net (cause browser have issues with 'localhost' (for cross origin scripting)

Windows Vista and Windows 7 Vista and Windows 7 use User Account Control (UAC) so Notepad must be run as Administrator.

  1. Click Start -> All Programs -> Accessories

  2. Right click Notepad and select Run as administrator

  3. Click Continue on the "Windows needs your permission" UAC window.

  4. When Notepad opens Click File -> Open

  5. In the filename field type C:\Windows\System32\Drivers\etc\hosts

  6. Click Open

  7. Add this to your %WINDIR%\System32\drivers\etc\hosts file: 127.0.0.1 localdev.YOURSITE.net

  8. Save

  9. Close and restart browsers

On Mac or Linux:

  1. Open /etc/hosts with su permission
  2. Add 127.0.0.1 localdev.YOURSITE.net
  3. Save it

When developing you use localdev.YOURSITE.net instead of localhost so if you are using run/debug configurations in your ide be sure to update it.

Use ".YOURSITE.net" as cookiedomain (with a dot in the beginning) when creating the cookiem then it should work with all subdomains.

2) create the certificate using that localdev.url

TIP: If you have issues generating certificates on windows, use a VirtualBox or Vmware machine instead.

3) import the certificate as outlined on http://www.charlesproxy.com/documentation/using-charles/ssl-certificates/

TroyWorks
  • 411
  • 8
  • 16
  • Hi Troy, thanks for sharing this. Someone else will have to comment on if this works or not. My workaround: I ended up adding dev.phantomjscloud.com to my hosts file, and then using my production cert. That is only useful if you want your production keys available on your dev box though, so I think your solution could still be valid, if someone else can please verify – JasonS May 15 '14 at 05:37
  • It works for me and my team, in a combination of ways, secure local to local server to secure local to production server. – TroyWorks May 16 '14 at 06:40
  • For Windows, the git bash console works great using openssl commands from [here](https://blog.didierstevens.com/2015/03/30/howto-make-your-own-cert-with-openssl-on-windows/). Just have to install the root certificate and you can create multiple site-specific certificates signed by it if you want. – Jason Goemaat May 06 '17 at 01:04
6

For windows, follow these simple steps.

  1. Open Windows PowerShell, run as administrator
  2. install Chocolatey following this hyperlink.
  3. use choco install mkcert to install mkcert.
  4. run mkcert -install will create local CA.
  5. run mkcert localhost 127.0.0.1 ::1 will create a trusted cert for localhost in the current directory.
  6. Use the generated ./localhost+2.pem and ./localhost+2-key.pem in your server as cert and key respectively. (adding key and cert varies from server to server.)
  7. Finally run your server using the setup described in various other answers (For Express server, it is given below)
    const https = require('https');
    const fs = require('fs');
    const express = require('express');

    const app = express();


    app.get('/', function(req, res){
      res.send("HELLO!");
    });

    const server = https.createServer({
        key: fs.readFileSync('./localhost+2-key.pem'), // path to localhost+2-key.pem
        cert: fs.readFileSync('./localhost+2.pem'), // path to localhost+2.pem
        requestCert: false,
        rejectUnauthorized: false,
    }, app).listen(3000, function(){
      console.log("Successfully started server on port 3000");
    });

then run your server using node server.js

  1. On your browser use https://localhost:3000 and you will see a lock in address bar.

Enjoy!!

Deepak Singh
  • 71
  • 1
  • 1
4

If you're on OSX/Chrome you can add the self-signed SSL certificate to your system keychain as explained here: http://www.robpeck.com/2010/10/google-chrome-mac-os-x-and-self-signed-ssl-certificates

It's a manual process, but I got it working finally. Just make sure the Common Name (CN) is set to "localhost" (without the port) and after the certificate is added make sure all the Trust options on the certificate are set to "Always Trust". Also make sure you add it to the "System" keychain and not the "login" keychain.

Vijay Rudraraju
  • 189
  • 1
  • 5
4

Go to: chrome://flags/

Enable: Allow invalid certificates for resources loaded from localhost.

You don't have the green security, but you are always allowed for https://localhost in chrome.

Alphapage
  • 901
  • 1
  • 6
  • 29
3

If you're using node, why not generate them with node? This module seems to be pretty full featured:

Note that I wouldn't generate on the fly. Generate with some kind of build script so you have a consistent certificate and key. Otherwise you'll have to authorize the newly generated self-signed certificate every time.

B T
  • 57,525
  • 34
  • 189
  • 207
2

on windows I made the iis development certificate trusted by using MMC (start > run > mmc), then add the certificate snapin, choosing "local computer" and accepting the defaults. Once that certificate snapip is added expand the local computer certificate tree to look under Personal, select the localhost certificate, right click > all task > export. accept all defaults in the exporting wizard.

Once that file is saved, expand trusted certificates and begin to import the cert you just exported. https://localhost is now trusted in chrome having no security warnings.

I used this guide resolution #2 from the MSDN blog, the op also shared a link in his question about that also should using MMC but this worked for me. resolution #2

mushcraft
  • 1,994
  • 1
  • 19
  • 27
2

There are more aspects to this.

You can achieve TLS (some keep saying SSL) with a certificate, self-signed or not.

To have a green bar for a self-signed certificate, you also need to become the Certificate Authority (CA). This aspect is missing in most resources I found on my journey to achieve the green bar in my local development setup. Becoming a CA is as easy as creating a certificate.

This resource covers the creation of both the CA certificate and a Server certificate and resulted my setup in showing a green bar on localhost Chrome, Firefox and Edge: https://ram.k0a1a.net/self-signed_https_cert_after_chrome_58

Please note: in Chrome you need to add the CA Certificate to your trusted authorities.

Jos
  • 419
  • 3
  • 12
2

SMH, a lot of hours wasted on this due to lack of proper documentation and not everyone uses IIS... If anyone else is still stuck on this issue I hope this helps.

Solution: Trusted Self Signed SSL CERT for localhost on Windows 10

Note: If you only need the SSL cert follow the Certification Creation section

Stack: Azure Function App(Node.js), React.js - Windows 10

Certification Creation

Step 1 - Create Certificate: OpenPowershell and run the following:

New-SelfSignedCertificate -NotBefore (Get-Date) -NotAfter (Get-Date).AddYears(5) `
-Subject "CN=localhost" -KeyAlgorithm "RSA" -KeyLength 2048 `
-HashAlgorithm "SHA256" -CertStoreLocation "Cert:\CurrentUser\My" `
-FriendlyName "HTTPS Development Certificate" `
-TextExtension @("2.5.29.19={text}","2.5.29.17={text}DNS=localhost")

Step 2 - Copy Certificate: Open Certificate Manager by pressing the windows key and search for "manage user certificates". Navigate to Personal -> Certificates and copy the localhost cert to Trusted Root Certification Authorities -> Certificates

Personal -> Certificates

Trusted Root Certification Authorities -> Certificates

(Friendly Name will be HTTPS Development Certificate)

Step 3. Export Certificate right click cert -> All Tasks -> Export which will launch the Certificate Export Wizard: Certificate Export Wizard

  • Click next
  • Select Yes, export the private Key Export private key
  • Select the following format Personal Information Exchange - PKCS #12 and leave the first and last checkboxes selected. Export format
  • Select a password; enter something simple if you like ex. "1111" Enter password
  • Save file to a location you will remember ex. Desktop or Sites (you can name the file development.pfx) Save file

Step 4. Restart Chrome

Azure Function App (Server) - SSL Locally with .PFX

In this case we will run an Azure Function App with the SSL cert.

  • copy the exported development.pfx file to your azure functions project root
  • from cmd.exe run the following to start your functions app func start --useHttps --cert development.pfx --password 1111" (If you used a different password and filename don't forget to update the values in this script)
  • Update your package.json scripts to start your functions app:

React App (Client) - Run with local SSL

Install openssl locally, this will be used to convert the development.pfx to a cert.pem and server.key. Source - Convert pfx to pem file

  1. open your react app project root and create a cert folder. (project-root/cert)
  2. create a copy of the development.pfx file in the cert folder. (project-root /cert/development.pfx)
  3. open command prompt from the cert directory and run the following:
  4. convert development.pfx to cert.pem: openssl pkcs12 -in development.pfx -out cert.pem -nodes
  5. extract private key from development.pfx to key.pem: openssl pkcs12 -in development.pfx -nocerts -out key.pem
  6. remove password from the extracted private key: openssl rsa -in key.pem -out server.key
  7. update your .env.development.local file by adding the following lines:
SSL_CRT_FILE=cert.pem
SSL_KEY_FILE=server.key
  1. start your react app npm start
Brandon
  • 71
  • 1
  • 2
  • there are so many explanations online on how to use powershell for self signed certificate creationn. And all of them fail at some point (powershell script failing, export does not allow setting passward etc.). Finally this one worked for me. – Welcor Feb 11 '23 at 11:12
1

If you need to go a step further than @alon's detailed steps and also create a self signed ca:

https.createServer({
  key: fs.readFileSync(NODE_SSL_KEY),
  cert: fs.readFileSync(NODE_SSL_CERT),
  ca: fs.readFileSync(NODE_SSL_CA),
}, app).listen(PORT, () => {});

package.json

"setup:https": "openssl genrsa -out src/server/ssl/localhost.key 2048
&& openssl req -new -x509 -key src/server/ssl/localhost.key -out src/server/ssl/localhost.crt -config src/server/ssl/localhost.cnf
&& openssl req -new -out src/server/ssl/localhost.csr -config src/server/ssl/localhost.cnf
&& openssl x509 -req -in src/server/ssl/localhost.csr -CA src/server/ssl/localhost.crt -CAkey src/server/ssl/localhost.key -CAcreateserial -out src/server/ssl/ca.crt",

Using the localhost.cnf as described:

[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = UK
ST = State
L = Location
O = Organization Name
OU = Organizational Unit 
CN = www.localhost.com
[v3_req]
keyUsage = critical, digitalSignature, keyAgreement
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = www.localhost.com
DNS.2 = localhost.com
DNS.3 = localhost
mummybot
  • 2,668
  • 2
  • 28
  • 31
1

To follow up on answers from @Alon and @Diego above, the following should eliminate some of the manual browsers steps:

  1. Create your request config file [as ./req.cnf]:
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = NG
ST = Lagos
L = Ikeja
O = Acme
OU = Dev 
CN = localhost
[v3_req]
keyUsage = critical, digitalSignature, keyAgreement
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = www.localhost.com
DNS.2 = localhost.com
DNS.3 = localhost
  1. Create your certificate files [by running the following in your terminal]:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout client-cert.key -out client-cert.pem -config req.cnf -sha256
  1. Add as trusted certificates to your Keychain:
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ./client-cert.pem

Note: Update the req.cnf according to your specific location, etc.

Note: This procedure was tested on MacOS High Sierra (10.13.6). If you're on Windows, you may need an alternative command for Step 3.

ObiHill
  • 11,448
  • 20
  • 86
  • 135
0

in my case the .cert always change to default ( thats mean denied ) what ever we have change to always trusted. my device is macOS.

  1. command + space , type keychain access and open it.
  2. so we need to drag and drop into System Keychains -> System for the .cert file and double click on file -> get info -> make it change always trusted
  3. so my chrome for localhost or 127.0.0.1 the hyperlink proccess unsafe are visible , before its gone type.
openssl genrsa -out server.key 2048
openssl req -new -x509 -key server.key -out server.cert -days 365
Yogi Arif Widodo
  • 563
  • 6
  • 22