javascript - 无法在 Node.js 中使用 IP 作为自签名证书

标签 javascript node.js https openssl self-signed

我正在尝试在 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/

相关文章:

curl - 使用 Git 的 libcurl 中不支持或禁用协议(protocol) https

javascript - 音频同步,每1/44.1毫秒调用一次函数

javascript - 如何获取 Google Places 请求对象以在我的网站中使用以显示评论

javascript - Node.js 在循环和处理对象数组时异步丢失上下文

javascript - 如何在 Node 中 promise 和等待 setImmediate?

javascript - axios 和 Express 路由器没有预期错误

Java SSL Connect 获得 403 而 curl -E 成功

ssl - SSL HTTP 和 HTTPS 之间有什么区别吗?

javascript - 返回按钮从 javascript 模板加载相关的 html

javascript - 如何在滚动时进行页面转换