我正在尝试在 Node.js 中使用 HTTP 自签名证书。
我使用我编写的以下脚本生成了证书:
生成.sh
#!/bin/bash
read -p "FQDN: " FQDN
# for easy testing
rm ROOT.*
rm SERVER.*
openssl genrsa 4096 > ROOT.key
openssl req -x509 -nodes -sha256 -new -key ROOT.key -days 365 -subj "/C=AU/CN=example" > ROOT.crt
openssl req -newkey rsa:4096 -nodes -sha256 -keyout SERVER.key -subj "/C=AU/CN=${FQDN}" > SERVER.csr
openssl x509 -days 365 -req -in SERVER.csr -CA ROOT.crt -CAkey ROOT.key -CAcreateserial > SERVER.crt
我正在尝试使用以下方法测试证书:
test.js
let fs = require('fs')
let https = require('https')
// HTTP server
https.createServer({
key: fs.readFileSync('SERVER.key'),
cert: fs.readFileSync('SERVER.crt'),
ca: fs.readFileSync('ROOT.crt')
}, function (req, res) {
res.writeHead(200)
res.end('Hello world')
}).listen(4433)
// HTTP request
let req = https.request({
hostname: '127.0.0.1',
port: 4433,
path: '/',
method: 'GET',
ca: fs.readFileSync('ROOT.crt')
}, function (res) {
res.on('data', function (data) {
console.log(data.toString())
})
})
req.end()
但是,经过测试:
> node test.js
Error: Hostname/IP doesn't match certificate's altnames: "IP: 127.0.0.1 is not in the cert's list: "
这看起来很奇怪,因为如果我打印证书证书列表,它会显示 IP 在那里?
如果我使用 localhost
作为 FQDN 和 host
(在请求中),它确实有效。
我错过了什么?
编辑:
curl --cacert ROOT.crt https://127.0.0.1:4433
完成且没有错误,那么我在 Node.js 代码中缺少什么?
最佳答案
感谢 Kris Reeves 为我指明了正确的方向。
问题如前所述,证书丢失subjectAltName
s,并以与 Node 兼容的格式获取它们并不是那么简单(必须与 X509v3 兼容)。
决赛Makefile
结果是这样的:
.PHONY: clean default
FQDN ?= 127.0.0.1
default: SERVER.crt
clean:
rm -f openssl.conf
rm -f ROOT.*
rm -f SERVER.*
openssl.conf:
cat /etc/ssl/openssl.cnf > openssl.conf
echo "[ san_env ]" >> openssl.conf
echo "subjectAltName=$$""{ENV::SAN}" >> openssl.conf
ROOT.key:
openssl genrsa 4096 > ROOT.key
ROOT.crt: ROOT.key
openssl req \
-new \
-x509 \
-nodes \
-sha256 \
-key ROOT.key \
-days 365 \
-subj "/C=AU/CN=example" \
-out ROOT.crt
SERVER.csr: openssl.conf
SAN=IP:$(FQDN) openssl req \
-reqexts san_env \
-config openssl.conf \
-newkey rsa:4096 \
-nodes -sha256 \
-keyout SERVER.key \
-subj "/C=AU/CN=$(FQDN)" \
-out SERVER.csr
SERVER.crt: openssl.conf ROOT.key ROOT.crt SERVER.csr
SAN=IP:$(FQDN) openssl x509 \
-req \
-extfile openssl.conf \
-extensions san_env \
-days 365 \
-in SERVER.csr \
-CA ROOT.crt \
-CAkey ROOT.key \
-CAcreateserial \
-out SERVER.crt
希望这可以帮助其他想要使用仅具有 IP 的自签名证书的人。
$ make FQDN=127.0.0.1
关于javascript - 无法在 Node.js 中使用 IP 作为自签名证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33558076/