8

I'm trying to setup a site on localhost using a self-signed certificate for Express.js on Windows 10. Here is the Express.js server code.

index.js

const https = require('https')
const express = require('express')
const app = express()
const fs = require('fs')
const path = require('path')

const httpsOptions = {
    cert: fs.readFileSync(path.resolve(__dirname, 'ssl', 'ca.crt')),
    key: fs.readFileSync(path.resolve(__dirname, 'ssl', 'ca.key'))
}

const router = require('./router')

app.use('/people', router)

https.createServer(httpsOptions, app)
    .listen(3443)

I have also imported the certificate authority ca.crt file to chrome, and restarted chrome. But I still have error on chrome as shown below:

enter image description here

Please guide how to solve this problem Thanks


I created the keys and certificate using the following commands.

# certificate authority key
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out ca.key

# server key
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out server.key

# certificate authority
openssl req -new -x509 -days 365 -key ca.key -subj "/CN=Test CA/O=Test Organization" -out ca.crt

# certificate signing request
openssl req -new -key server.key -subj "/CN=localhost/O=Test Organization" -out server.csr

# server certificate
openssl x509 -days 365 -req -in server.csr -CAcreateserial -CA ca.crt -CAkey ca.key -out server.crt

# verification
openssl verify -verbose -CAfile ca.crt server.crt

System Info

  • OpenSSL: 1.1.0e 16 Feb 2017
  • Node: 7.7.1
  • Windows 10
jww
  • 90,984
  • 81
  • 374
  • 818
Artisan
  • 3,734
  • 13
  • 35
  • 56
  • 1
    You might want to look [here](http://stackoverflow.com/questions/27294589/creating-self-signed-certificate-for-domain-and-subdomains-neterr-cert-commo), it seems to be similar to your issue – Frederic Mar 15 '17 at 17:50
  • 3
    Your end-entity/server certificate is malformed. ***`CN=localhost`*** is wrong. Hostnames always go in the *SAN*. If its present in the *CN*, then it must be present in the *SAN* too (you have to list it twice in this case). For more rules and reasons, see [How do you sign Certificate Signing Request with your Certification Authority](http://stackoverflow.com/a/21340898/608639) and [How to create a self-signed certificate with openssl?](http://stackoverflow.com/q/10175812/608639) – jww Mar 15 '17 at 18:28
  • 1
    @jww CN = Common Name, what does SAN stand for? – Dominic Dec 29 '17 at 12:31
  • *SAN* might be `Subject Alternative Names` – XoXo May 26 '20 at 18:49

1 Answers1

7

Spent a couple of hours trying to fix this. The following way worked for me:

Create a config file (for example req.cnf)

[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
  [req_distinguished_name]
C = US
ST = VA
L = SomeCity
O = MyCompany
OU = MyDivision
CN = local.com
  [v3_req]
keyUsage = critical, digitalSignature, keyAgreement
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
  [alt_names]
DNS.1 = local.com
IP.1 = 127.0.0.1

and then generate a certificate and private key

 openssl req -x509 -nodes -days 730 -newkey rsa:2048 -keyout local.com.key -out local.com.crt -config req.cnf -sha256
Alex Vasilev
  • 717
  • 8
  • 18
  • 3
    This solution did not work for me while tested in windows server. Still getting the same error in chrome ERR_CERT_INVALID_COMMON_NAME – Naga Feb 27 '19 at 03:26
  • 1
    This was the correct magical incantation to make Chrome trust the cert for me - huge thanks! Small suggestion - when using `openssl` to generate the cert, specify the certificate as `local.crt` because, by default, Chrome's Certificate Import Wizard looks for `*.cer *.crt` so the next person along might not see their file. – agtb Nov 06 '20 at 15:56
  • Other tips for the next person: don't forget to import the cert in Chrome (Settings, search *Manage certificates*) in *Trusted Root Certification Authorities* and then restart Chrome `chrome://restart` – agtb Nov 06 '20 at 16:04