本教程向您展示如何为 Node.js 应用程序生成 CSR。Node.js 没有内置的 CSR 生成工具,因此您需要在将运行 Node 的机器上使用 OpenSSL 创建私钥和证书签名请求(CSR),将 CSR 提交给您的证书颁发机构,然后使用 fs.readFileSync() 和 https.createServer() 将颁发的证书加载到您的应用程序中。
以下步骤适用于任何附带 OpenSSL 的操作系统,涵盖当前所有 Linux 发行版、macOS 和 Windows(通过官方 OpenSSL 二进制文件或 Git Bash)。现代 OpenSSL 默认使用 SHA-256 对请求进行签名,因此您无需添加摘要标志。
第一步:确保已安装 OpenSSL
检查将运行您的 Node.js 应用程序的机器上是否已安装 OpenSSL:
openssl version
您应该会看到类似 OpenSSL 3.0.x 或更新版本的信息。如果找不到该命令,请为您的平台安装它:
- Debian、Ubuntu:
sudo apt update && sudo apt install openssl - RHEL、AlmaLinux、Rocky Linux、Amazon Linux:
sudo dnf install openssl(在较旧版本上使用sudo yum install openssl) - macOS: OpenSSL(某些版本为 LibreSSL,若通过 Homebrew 安装则为 OpenSSL 3)已内置于终端中。若要安装官方源版本:
brew install openssl@3。 - Windows: 安装官方 OpenSSL 二进制文件,或使用预装了 OpenSSL 的 Git Bash。
第二步:生成私钥和 CSR
在将运行 Node.js 的机器上生成密钥和 CSR。私钥会与 CSR 一起创建,并且必须保留在该机器上。若在别处运行这些命令,然后再把密钥复制过去,就失去了拥有私钥的意义。
运行以下命令。它可一步创建一个 2048 位的 RSA 私钥和一个匹配的 CSR,主题和使用者备用名称(SAN)都以内联方式提供,因此 OpenSSL 不会停下来询问问题:
openssl req -new -newkey rsa:2048 -nodes
-keyout yourdomain.key
-out yourdomain.csr
-subj "/C=US/ST=YourState/L=YourCity/O=YourCompany/CN=yourdomain.com"
-addext "subjectAltName=DNS:yourdomain.com,DNS:www.yourdomain.com"
各部分的作用如下:
- -newkey rsa:2048 生成一个新的 2048 位 RSA 密钥。2048 位是目前公共 CA 接受的最低要求;您可以使用 rsa:4096 生成更大的密钥,或改用 ECDSA(见下文)。
- -nodes 使私钥保持未加密状态,以便 Node.js 在启动时可以读取它,而无需提示输入密码。Node 的 https 模块确实支持为加密密钥设置 passphrase 选项,但该密码仍然必须来自机器上的某个位置(配置文件、环境变量或密钥管理服务)。
- -keyout 和 -out 分别命名私钥文件和 CSR 文件。
- -subj 提供证书主题。请在此处填写您的真实公司名称、州/省和城市,而不是占位符。CN(通用名称)是您的主域名。
- -addext “subjectAltName=…” 列出该证书必须覆盖的每个主机名。公共 CA 会根据 SAN 列表进行验证,因此这里也要包含通用名称。-addext 标志需要 OpenSSL 1.1.1 或更高版本,目前所有操作系统都自带该版本。
请将全文中的 yourdomain.com 替换为您的实际域名。要覆盖额外的主机名,请在 SAN 列表中用逗号分隔添加它们,例如 DNS:api.yourdomain.com。对于通配符证书,请同时包含通配符和裸域名:DNS:*.yourdomain.com,DNS:yourdomain.com。
如果您更喜欢 ECDSA 密钥(更小更快,并且广泛支持 P-256),可以改用以下方式生成密钥和 CSR:
openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -pkeyopt ec_param_enc:named_curve -nodes
-keyout yourdomain.key
-out yourdomain.csr
-subj "/C=US/ST=YourState/L=YourCity/O=YourCompany/CN=yourdomain.com"
-addext "subjectAltName=DNS:yourdomain.com,DNS:www.yourdomain.com"
交互模式(不使用 -subj)
如果您希望 OpenSSL 逐项提示您输入字段,请删除 -subj 标志:
openssl req -new -newkey rsa:2048 -nodes
-keyout yourdomain.key -out yourdomain.csr
-addext "subjectAltName=DNS:yourdomain.com,DNS:www.yourdomain.com"
OpenSSL 会要求您提供以下信息:
- 国家名称(C): 您所在组织的两字母 ISO 国家代码(例如 US)。
- 州或省名称(S): 您公司注册所在州或省的完整名称(例如 California)。请不要缩写。
- 地区名称(L): 您企业注册所在的城市(例如 San Jose)。
- 组织名称(O): 您公司的法定名称(例如 GPI Holding LLC)。对于 DV(域名验证)证书,请留空并按 Enter 键。
- 组织单位名称(OU): 自 2022 年 9 月起已被弃用,公共 CA 会忽略此字段。请留空。
- 通用名称(CN): 您要保护的完全限定域名(FQDN),例如 yourdomain.com。对于通配符证书,请使用 *.yourdomain.com。
- 电子邮件地址: 可选。留空即可。
- 挑战密码: 已过时。留空即可。
第三步:定位并保护您的文件
列出当前目录以确认两个文件都已创建:
ls
您应该会看到两个新文件:
- yourdomain.key:您的私钥。请将其保存在服务器上,进行安全备份,切勿发送给任何人,包括证书颁发机构。持有该密钥的人可以冒充您的网站。
- yourdomain.csr:您的证书签名请求。这是您提交给 SSL 提供商的文件。
在 Linux 或 macOS 上,请立即为私钥设置严格的权限,以便只有运行 Node.js 的用户才能读取它:
chmod 600 yourdomain.key
如果 Node.js 在专用服务账户下运行(例如 node 或 www-data),还应设置所有者,以便该进程可以读取密钥:
sudo chown node:node yourdomain.key
第四步:验证 CSR(可选,但推荐)
在提交之前,请检查 CSR 是否包含正确的主题和 SAN,以及其签名是否有效。以下命令使用 OpenSSL 在本地解码该请求:
openssl req -noout -text -verify -in yourdomain.csr
确认 Subject 行显示您的详细信息,X509v3 Subject Alternative Name 列出了您期望的每个主机名,并且签名检查结果显示 verify OK。签名算法应显示为 sha256WithRSAEncryption(对于 ECDSA 密钥则为 ecdsa-with-SHA256)。如果您不想使用命令行,可以将 CSR 粘贴到我们的在线CSR 解码工具中,在浏览器中查看相同的字段。
第五步:提交您的 CSR
要复制订单所需的 CSR,请打印其内容:
cat yourdomain.csr
您将看到如下一段文本:
-----BEGIN CERTIFICATE REQUEST-----
MIIBozCB... (a long string of characters)
-----END CERTIFICATE REQUEST-----
复制整个区块,包括 —–BEGIN CERTIFICATE REQUEST—– 和 —–END CERTIFICATE REQUEST—– 这两行(每个标记两侧各有五个连字符)。整个区块就是您的 CSR。在购买过程中将其粘贴到订单表单中,并将匹配的私钥保存在服务器上。
如果您不想使用命令行,也可以使用我们的在线CSR 生成器来构建请求。请注意,它会在您的浏览器中生成私钥,因此请自行保存该密钥,并将其转移到 Node.js 服务器上。
CA 颁发证书后会发生什么
一旦 CA 验证了 CSR 并颁发了证书,您通常会收到您的服务器证书(一个以您的域名命名的 .crt 文件)以及一个或多个中间证书,有时会打包成一个 .ca-bundle 文件。Node.js 在 JavaScript 中加载这些文件:将服务器证书和中间证书连接成一个单一的 fullchain.crt 文件,然后使用 fs.readFileSync() 读取它,并将其传递给 https.createServer():
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('/path/to/yourdomain.key'),
cert: fs.readFileSync('/path/to/fullchain.crt'),
minVersion: 'TLSv1.2'
};
https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('Welcome to a Node.js HTTPS servern');
}).listen(443);
大多数生产环境的配置都使用这种完整证书链的模式。完整的操作步骤(包括一个 ES 模块示例、一种替代的 ca: 数组方法,以及一个 Express 示例)在我们的Node.js SSL 安装教程中有详细介绍。
关于生产环境部署的说明。 在 2026 年,大多数处理公共流量的 Node.js 应用程序都运行在反向代理或云负载均衡器(NGINX、HAProxy、Caddy、AWS ALB、Cloudflare、Fastly)之后,这些代理或负载均衡器在边缘终止 TLS,并将纯 HTTP 或 HTTP/2 转发到高位本地端口上的 Node。在这种模式下,证书(以及您上面生成的 CSR)位于代理或负载均衡器上,而不是 Node 进程本身。让 Node.js 直接终止 TLS 对于开发环境、内部服务和小型部署来说完全没问题;对于公共生产应用程序而言,在边缘终止 TLS 是更常见的做法。


