我正在尝试创建自签名证书,以便在本地测试某些 SSL 功能。 为了创建自签名证书,我执行了以下步骤:
第1步.创建Root crt / key用于自签名
openssl req -nodes -x509 -sha256 -days 1825 -newkey rsa:2048 -keyout rootCA.key -out rootCA.crt
第2步.使用openssl创建CSR
openssl req -nodes -newkey rsa:2048 -keyout domain.key -out domain.csr
第 3 步:使用证书的主题替代名称创建域文件
手动创建文件domain.ext,内容如下:
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = desktop-3dqn06e
DNS.3 = 192.168.56.1.nip.io
IP.1 = 192.168.56.1
步骤 4.使用 Root crt/key 文件生成自签名证书
openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in domain.csr -out domain.crt -days 1825 -CAcreateserial -extfile domain.ext
第 5 步.运行基本的 Express Web 服务器来测试证书
var path = require('path');
var fs = require('fs');
var express = require('express');
var http = require('http');
let https = require('https');
var tls = require('tls');
// create new express app and assign it to `app` constant
const app = express();
/***
* Start the server: listens on http://localhost:${PORT}
*/
//SSL credentials
function getCredentials(){
let privateKey = fs.readFileSync('/path/to/domain.key', 'utf8');
let certificate = fs.readFileSync('/path/to/domain.crt'), 'utf8');
let certauth = fs.readFileSync('/path/to/rootCA.crt'), 'utf8');
let credentials = {key: privateKey, cert: certificate, ca: certauth};
return credentials;
}
var ctx = function() { return tls.createSecureContext(getCredentials()) };
//Start HTTPS server
const httpsServer = https.createServer({
SNICallback: (servername, cb) => cb(null, ctx())
}, app);
httpsServer.listen(443);
//Redirect HTTP requests to HTTPS
const httpServer = http.createServer(function (req, res) {
res.writeHead(301, { "Location": "https://" + req.headers['host'] + req.url });
res.end();
});
httpServer.listen(80);
//Send home page
app.get('/',function(req,res) {
res.sendFile(path.join(__dirname+'/index.html'));
});
当我尝试使用本地主机或计算机名称通过浏览器向服务器发出客户端请求时,连接正常,我可以看到连接是安全的
但是,如果我尝试使用在domain.ext中配置的网络IP进行访问,连接会失败并显示
ERR_SSL_VERSION_OR_CIPHER_MISMATCH
此外,nip.io 等效地址也失败,并显示 DNS_PROBE_FINISHED_NXDOMAIN
...如果我尝试使用在domain.ext中配置的网络IP进行访问,连接会失败并显示ERR_SSL_VERSION_OR_CIPHER_MISMATCH
您仅在 SNICallback 中提供 SSL 上下文。但是,如果仅使用 IP 地址,则不会使用 SNI,因此不会调用 SNICallback。因此,不知道证书的上下文,这意味着服务器仅支持不需要证书的密码,这意味着客户端提供的密码没有重叠(即仅需要证书的密码)。
因此,您还需要为 createServer 提供在 getCredentials 中构造的参数,以便在没有 SNI 的情况下调用它时具有有用的上下文。
此外,nip.io 等效地址也因 DNS_PROBE_FINISHED_NXDOMAIN 失败
这是一个 DNS 问题,即发生在 TCP 连接创建之前,这也意味着在 TLS 握手完成之前。因此,这与 TLS 问题无关。我不知道为什么失败,DNS 查找对我有用。