680 字
3 分钟
解决本地开发中 OpenSSL 生成自签证书的常见问题

为什么需要自签证书?#

在开发涉及 Service WorkersWebAuthn 或某些 OAuth 2.0 回调的功能时,浏览器要求必须在 HTTPS 环境下运行。自签证书允许我们在本地 localhost 模拟生产环境的加密通信。

核心痛点:避开 -des3#

许多旧教程推荐使用 -des3 参数。这会给私钥增加密码保护,导致 Node.js 每次启动时都需要手动输入密码,甚至在自动化部署中引发崩溃。去掉该参数可以生成“免密”私钥,更加适合开发环境。


正确的生成步骤#

1. 生成 RSA 私钥#

我们建议使用 2048 位长度,这是目前安全与性能的平衡点。

Terminal window
openssl genrsa -out server.key 2048
  • server.key: 你的私钥文件,请务必妥善保管,不要上传到公共 Git 仓库。

2. 生成证书签名请求 (CSR)#

虽然可以手动输入信息,但在现代浏览器中,最重要的字段是 Common Name (填入 localhost)。

Terminal window
openssl req -new -key server.key -out server.csr

3. 生成自签名证书(带 SAN 扩展)#

重要更新: 现代浏览器(Chrome 58+)不再仅信任 Common Name。如果证书中没有 subjectAltName,浏览器仍会提示“不安全”。

建议创建一个临时文件 cert.ext,内容如下:

subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP.1 = 127.0.0.1

然后执行生成命令:

Terminal window
openssl x509 -req -in server.csr -signkey server.key -out server.crt -days 3650 -extfile cert.ext
  • -days 3650: 设置有效期为 10 年,免去频繁更新的烦恼。

如何在 Node.js/npm 项目中使用?#

生成 server.keyserver.crt 后,你可以在 Node.js 应用中直接引用:

const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server.crt')
};
https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('Hello Secure World\n');
}).listen(443);

如果是使用 webpack-dev-server,可以在 package.json 的启动脚本中配置:

"scripts": {
"start": "webpack-dev-server --https --key server.key --cert server.crt"
}

避坑指南与最佳实践#

⚠️ 注意事项:

  1. 浏览器信任:生成证书后,双击 server.crt 并将其安装到系统的“受信任的根证书颁发机构”中,否则浏览器仍会显示红色警告。

  2. 安全风险:自签证书仅限本地开发。切勿在生产环境中使用自签证书,生产环境请使用 Let’s Encrypt 提供的免费证书。

  3. 密钥位数:避免使用 1024 位,某些现代安全库已默认不再支持 1024 位 RSA 密钥。


总结#

通过移除不必要的加密参数(如 -des3)并添加现代浏览器强制要求的 SAN 扩展,你可以快速搭建一个稳定的本地 HTTPS 开发环境。这不仅能解决 npm 启动时的报错,还能让你在本地开发时获得与线上一致的安全性体验。

解决本地开发中 OpenSSL 生成自签证书的常见问题
https://sw.rscclub.website/posts/opensslerror/
作者
杨月昌
发布于
2019-02-18
许可协议
CC BY-NC-SA 4.0