I'm having issues using Node.js on Windows to access an HTTPS site running locally in IIS Express, using a self-signed cert. Code to reproduce:
const https = require("https");
const req = https.request(
{
hostname: "localhost",
path: "/api/heroes",
port: 44323,
method: "GET"
},
res => res.on("data", console.log)
);
req.on("error", console.error);
Running this with node test.js
gives:
Error: unable to verify the first certificate
at TLSSocket.onConnectSecure (_tls_wrap.js:1321:34)
at TLSSocket.emit (events.js:223:5)
at TLSSocket._finishInit (_tls_wrap.js:794:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:608:12) {
code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'
}
I can access the page in Chrome without issues; Chrome sees the cert as trusted. I also see the cert in certmgr
under Trusted Root Certification Authorities for the current user. I've tried exporting the cert as a PEM, then pointing NODE_EXTRA_CA_CERTS
to it; I've also tried creating an https.Agent
with its ca
property set by reading in the cert. Both give the same error.
Viewing the cert with `openssl x509 -in cert.pem -noout -text gives the following:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
4d:16:7e:86:ce:1a:56:97:48:62:21:cc:7f:ce:ac:55
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=localhost
Validity
Not Before: Oct 6 02:20:56 2018 GMT
Not After : Oct 5 00:00:00 2023 GMT
Subject: CN=localhost
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:db:6c:55:9e:a5:a8:83:7f:ed:0b:62:88:9c:16:
05:31:64:fe:e7:23:73:0a:9e:5e:49:90:c8:ca:98:
b5:96:52:ad:36:79:17:81:54:bd:99:99:a1:c3:d3:
94:e3:34:83:24:ae:64:e4:33:a7:70:cf:fd:a1:91:
df:fb:c4:e5:62:c1:5a:ab:dd:42:e2:b3:33:38:99:
9a:be:10:a4:9a:a7:aa:a6:30:59:a6:29:25:3f:95:
2f:7e:c8:79:42:8f:d5:54:c1:2b:5e:91:3c:7c:53:
e2:34:68:51:21:f2:1a:71:66:78:1c:fc:93:f7:f8:
7e:70:43:22:4f:53:8c:5a:9b:08:ef:d4:af:79:b1:
be:be:7c:bd:cf:04:9b:30:7f:a7:19:f6:dc:3c:30:
b2:6f:83:fd:45:65:1c:2e:66:ad:d6:fc:d6:3d:09:
60:53:32:c7:13:24:80:44:25:05:81:41:61:f0:65:
32:1a:1b:b2:c7:a0:bb:52:d9:a9:5d:75:4d:d8:ac:
6a:d6:e2:97:d8:e0:cc:1b:1e:bf:05:e6:c5:11:69:
89:c8:c4:d1:fe:8c:d2:f6:f0:04:bb:38:c7:50:7f:
a7:78:80:03:27:a6:86:86:78:d7:5d:d3:cb:47:09:
b6:f6:ca:a2:c8:51:95:e2:85:3d:46:74:4f:50:b2:
7f:75
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage:
Digital Signature, Key Encipherment, Data Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Alternative Name:
DNS:localhost
Signature Algorithm: sha256WithRSAEncryption
45:c4:44:60:e6:bc:a2:8f:8f:db:5e:7c:33:14:a6:59:d7:7e:
ef:88:e6:75:21:dc:df:3e:3b:be:7c:0e:c7:f4:1e:84:0c:56:
05:78:41:08:7a:97:f7:47:d9:6f:91:39:b3:9f:0b:b2:e0:c9:
49:08:3b:9a:80:fd:07:3d:cc:55:21:d2:52:27:f3:a0:f2:35:
a8:0c:56:0d:4b:c9:20:e1:94:8d:43:b6:f3:72:55:5e:0d:27:
55:0e:b5:72:26:90:65:fb:28:98:87:bd:c8:68:d5:44:a6:69:
af:0b:2e:20:e2:4c:7b:50:68:9d:25:56:3c:0d:2d:b9:54:0b:
21:cf:71:f5:92:ad:b5:72:8f:88:3e:d5:3f:54:40:58:d3:1c:
40:99:3a:1f:59:40:81:52:39:55:cf:2f:7e:18:27:86:6b:67:
82:c3:d0:2d:93:91:b3:5b:02:b5:3a:8a:46:90:93:20:ed:09:
4e:7a:37:f6:21:2b:84:5d:eb:bc:96:63:cd:08:24:4a:0d:ee:
8a:86:d3:6c:f8:3c:0d:4f:6a:a7:e1:ca:17:83:bb:5e:99:ff:
87:19:a1:d5:b9:b9:54:59:41:44:32:36:20:bd:3f:4d:ad:6d:
4f:11:c6:76:77:2d:d7:9e:21:17:eb:d5:fd:a2:58:0a:dc:1d:
14:5e:d2:f3
I know there are workarounds involving disabling checking certs (or just running the API on plain HTTP locally), but I'm really curious and befuddled why it won't work with HTTPS. Any help is greatly appreciated.