如何在Node.js中使用免费SSL证书?

更新时间:2025-07-17 来源:sitepoint 作者:TopSSL

如何在Node.js中使用免费SSL/TLS证书?在本教程中,我们将通过一个实际示例,向您介绍如何将Let's Encrypt生成的免费ssl证书添加到您的Express.js服务器。

如何在Node.js中使用免费SSL证书?

2025年的网站已经没有理由不使用HTTPS。访客对此有期待,谷歌百度将其作为排名因素,并且浏览器厂商会乐于点名批评那些不使用HTTPS的网站。
在本教程中,我将通过一个实际示例,向您介绍如何将Let's Encrypt生成的免费ssl证书添加到您的Express.js服务器。

然而,仅仅使用HTTPS保护我们的网站和应用程序还不够。我们还应该要求与我们通信的服务器建立加密连接。我们将看到,即使SSL/TLS层默认未启用,也存在激活该层的可能性。

注意: 如果您正在寻找关于在将NGINX配置为Node应用程序的反向代理时,如何使用NGINX设置SSL的说明,请查看我们的快速提示“使用Node.js配置NGINX和SSL”。

让我们首先简要回顾一下HTTPS的当前状态。

关键要点

  • HTTPS对于2025年的网站至关重要,它提供身份验证、隐私、机密性和数据完整性。它也是Google排名的一个因素,并且是访客所期望的。
  • Node.js默认通过HTTP提供内容,但可以使用内置的 HTTPS模块通过安全通道与客户端进行通信。这需要生成SSL证书,可以使用Let's Encrypt免费生成。
  • Certbot可用于生成和管理Let's Encrypt的证书。它确保证书持有者的身份与其声明的身份相符,从而在客户端和服务器之间建立安全的连接。
  • HTTP严格传输安全(HSTS)可用于强制客户端通过HTTPS传输所有流量,从而缓解协议降级攻击和Cookie劫持。此功能可以通过Node模块 Helmet实现。
  • 可以通过生成更长(2048位)的Diffie-Hellman密钥来增强SSL/TLS证书的安全性,该密钥用于服务器的密钥交换。此密钥是证书颁发机构(CA)颁发的证书的补充。

无处不在的HTTPS

HTTP/2规范于2015年5月以RFC 7540的形式发布,这意味着它目前已成为标准的一部分。这是一个重要的里程碑。现在我们都可以升级服务器以使用HTTP/2。其中最重要的一点是它向后兼容HTTP 1.1,并提供了选择其他协议的协商机制。虽然该标准没有强制加密,但目前还没有浏览器支持未加密的HTTP/2。这为HTTPS带来了又一次提升。我们最终将实现HTTPS的无处不在!

我们的技术栈实际上是什么样的?从在浏览器中运行的网站(在应用程序级别)的角度来看,我们必须遍历以下层才能到达IP级别:

  • 客户端浏览器
  • HTTP
  • SSL/TLS
  • TCP
  • IP

HTTPS只不过是SSL/TLS之上的HTTP协议。因此,HTTP的所有规则仍然适用。这层附加协议实际上给我们带来了什么?它有诸多优势:我们可以通过密钥和证书进行身份验证;由于连接采用非对称加密,因此可以保证一定的隐私和机密性;此外,由于传输过程中数据无法更改,因此数据完整性也得到了保护。

最常见的误解之一是使用SSL/TLS计算成本高昂,并且会降低服务器速度。现在这显然已经过时了。我们也不需要任何带有加密单元的专用硬件。即使对于Google来说,SSL/TLS层也只占CPU负载的不到1%,而HTTPS的网络开销相比HTTP也低于2%。总而言之,为了一点开销而放弃HTTPS是没有意义的。

使用SSL/TLS计算成本高昂

正如Ilya Grigorik所说,只有一个性能问题:

TLS 只有一个性能问题:它的使用范围不够广泛。其他方面都可以优化:https://t.co/1kH8qh89Eg

— 伊利亚·格里戈里克 (@igrigorik) 2014 年 2 月 20 日

最新版本是TLS 1.3。TLS是SSL的后继者,其最新版本是SSL 3.0。从SSL到TLS的变更阻碍了互操作性,但基本流程保持不变。我们拥有三种不同的加密通道:第一种是用于证书链的公钥基础设施;第二种是用于密钥交换的公钥加密;最后,第三种是对称加密,这里我们使用加密技术进行数据传输。

TLS 1.3在一些重要操作中使用哈希算法。理论上,可以使用任何哈希算法,但强烈建议使用SHA2或更强大的算法。SHA1长期以来一直是标准,但最近已被淘汰。

HTTPS也越来越受到客户的关注。隐私和安全问题一直存在,但随着在线可访问数据和服务的不断增长,人们的担忧也越来越强烈。对于那些尚未实现HTTPS的网站,有一个实用的浏览器扩展程序——EFF的HTTPS Everywhere——可以加密我们与大多数网站的通信。

该插件的创建者意识到许多网站仅部分支持HTTPS。该插件允许我们针对这些仅部分支持HTTPS的网站重写请求。或者,我们也可以完全阻止HTTP(参见上图)。

基本通信

证书的验证过程包括验证证书签名和有效期。我们还需要验证它是否链接到受信任的根证书。最后,我们需要检查它是否已被撤销。世界上有一些专门的、值得信任的机构来颁发证书。如果其中一个机构被盗用,该机构颁发的所有其他证书都将被撤销。

HTTPS握手的序列图如下所示。首先从客户端进行初始化,然后发送包含证书和密钥交换的消息。服务器发送其完整的数据包后,客户端可以开始密钥交换和密码规范传输。至此,客户端操作完成。最后,服务器确认密码规范选择并结束握手。

整个序列独立于HTTP触发。如果我们决定使用HTTPS,则仅套接字处理会有所改变。客户端仍在发出HTTP请求,但套接字将执行前面描述的握手并加密内容(标头和正文)。

那么我们需要做什么才能使SSL/TLS与Express.js服务器一起工作?

HTTPS

默认情况下,Node.js通过HTTP提供内容。但为了通过安全通道与客户端进行通信,我们还必须使用 HTTPS模块。这是一个内置模块,其用法与 HTTP模块非常相似:

JavaScript

const https = require("https"),
  fs = require("fs");
const options = {
  key: fs.readFileSync("/srv/www/keys/my-site-key.pem"),
  cert: fs.readFileSync("/srv/www/keys/chain.pem")
};
const app = express();
app.use((req, res) => {
  res.writeHead(200);
  res.end("hello world\n");
});
app.listen(8000);
https.createServer(options, app).listen(8080);

暂时忽略 /srv/www/keys/my-site-key.pem/srv/www/keys/chain.pem文件。这些是我们接下来需要生成的SSL证书。这部分正是Let's Encrypt带来的改变。以前,我们必须生成一对私钥/公钥,将其发送给可信机构,付款,然后可能还要等待一段时间才能获得SSL证书。现在,Let's Encrypt可以立即免费生成并验证您的证书!

获取并生成免费证书

Certbot

TLS规范要求证书由受信任的证书颁发机构(CA)签名。CA确保证书持有者的身份与其声称的身份相符。因此,当您在浏览器中看到绿色锁图标(或URL左侧任何其他绿色符号)时,意味着您正在与之通信的服务器确实与其声称的身份相符。topssl.cn上看到绿色锁图标,则几乎可以肯定您正在与网络k通信,并且没有其他人可以看到您的通信——或者更确切地说,没有其他人可以读取它。

image

值得注意的是,此证书不一定需要由Let's Encrypt等机构验证。还有其他付费服务。理论上,您可以自行签名,但这样一来(由于您不是受信任的CA),访问您网站的用户可能会看到一条巨大的警告信息,提示他们如何恢复安全。

在下面的示例中,我们将使用Certbot,它用于使用Let's Encrypt生成和管理证书。

在Certbot网站上,您可以找到如何在几乎所有操作系统/服务器组合上安装Certbot的说明。您应该选择适合您的选项。

部署Node应用程序的常见组合是在最新的LTS Ubuntu上使用NGINX,我将在这里使用它:

Bash

sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update

Webroot

Webroot是一个Certbot插件。除了Certbot的默认功能(自动生成公钥/私钥对并为其生成SSL证书)外,它还会将证书复制到您的webroot文件夹,并通过将一些验证码放入名为 .well-known的隐藏临时目录中来验证您的服务器。为了省去手动执行某些步骤的麻烦,我们将使用此插件。该插件默认随Certbot安装。为了生成和验证我们的证书,我们将运行以下命令:

Bash

certbot certonly --webroot -w /var/www/example/ -d www.example.com -d example.com

您可能必须以 sudo身份运行此命令,因为它将尝试写入 /var/log/letsencrypt

您还会被要求提供电子邮件地址。建议您输入一个经常使用的真实地址,因为如果您的证书即将到期,您会收到通知。Let's Encrypt颁发的免费证书每三个月到期一次。幸运的是,续订非常简单,只需运行一个简单的命令即可,我们可以将其分配给 cron作业,从此无需担心证书过期。此外,续订SSL证书是一种良好的安全措施,因为它可以减少攻击者破解加密的时间。有时开发人员甚至会将此cron设置成每天运行,这完全没问题,甚至值得推荐。

请记住,您必须在 -d(表示域名)标志下指定的域名解析到的服务器上运行此命令,也就是您的生产服务器。即使您的本地 hosts文件中有DNS解析,此命令也无法正常工作,因为该域名将从外部进行验证。因此,如果您在本地执行此操作,则很可能会失败,除非您从本地计算机打开一个到外部世界的端口,并让该命令运行在解析到您计算机的域名后面。这种情况极不可能发生。

最后但同样重要的一点是,运行此命令后,输出将包含您的私钥和证书文件的路径。将这些值复制到前面的代码片段中——cert属性用于证书,key属性用于密钥:

JavaScript

// ...
const options = {
  key: fs.readFileSync("/var/www/example/sslcert/privkey.pem"),
  cert: fs.readFileSync("/var/www/example/sslcert/fullchain.pem") // these paths might differ for you, make sure to copy from the certbot output
};
// ...

安全

HTTP严格传输安全 (HSTS)

您是否遇到过这样的情况:网站从HTTP切换到HTTPS后,仍然有一些重定向残留在HTTP上?HTTP严格传输安全(HSTS)是一种网络安全策略机制,用于缓解协议降级攻击和Cookie劫持。

HSTS有效地强制客户端(访问服务器的浏览器)通过HTTPS引导所有流量——这是一种“安全或完全不安全”的理念!

Express JS默认不允许我们添加此标头,因此我们将使用 Helmet,这是一个允许我们执行此操作的Node模块。通过运行以下命令安装 Helmet

Bash

npm install helmet

然后我们只需将其作为中间件添加到我们的Express服务器中:

JavaScript

const https = require("https"),
  fs = require("fs"),
  helmet = require("helmet");
const options = {
  key: fs.readFileSync("/srv/www/keys/my-site-key.pem"),
  cert: fs.readFileSync("/srv/www/keys/chain.pem")
};
const app = express();
app.use(helmet()); // Add Helmet as a middleware
app.use((req, res) => {
  res.writeHead(200);
  res.end("hello world\n");
});
app.listen(8000);
https.createServer(options, app).listen(8080);

Diffie–Hellman 强参数

为了省去一些复杂的数学运算,我们直接切入正题。简单来说,加密使用两个不同的密钥:一个是从证书颁发机构获得的证书,另一个是由服务器生成的用于密钥交换的密钥。密钥交换的默认密钥(也称为Diffie-Hellman密钥交换,简称DH)使用的密钥比证书密钥“短”。为了解决这个问题,我们将生成一个强DH密钥,并将其提供给我们的安全服务器使用。

为了生成更长的密钥(2048位),您需要 openssl,它可能已默认安装。如果您不确定,请运行 openssl -v。如果找不到该命令,请运行 sudo apt install openssl(或访问其下载页面)进行安装:

Bash

openssl dhparam -out /var/www/example/sslcert/dh-strong.pem 2048

然后将文件的路径复制到我们的配置中:

JavaScript

// ...
const options = {
  key: fs.readFileSync("/var/www/example/sslcert/privkey.pem"),
  cert: fs.readFileSync("/var/www/example/sslcert/fullchain.pem"), // these paths might differ for you, make sure to copy from the certbot output
  dhparam: fs.readFileSync("/var/www/example/sslcert/dh-strong.pem")
};
// ...

结论

在现在及未来,我们没有理由拒绝HTTPS。未来的行业方向清晰可见:HTTPS将无处不在!

常见问题解答

SSL/TLS在Node.js中的重要性是什么?

SSL/TLS在Node.js中至关重要,原因有很多。首先,它在客户端和服务器之间提供安全连接,确保两者之间传输的所有数据均经过加密,不会被第三方拦截。这对于处理敏感用户数据(例如登录凭据或支付信息)的应用程序尤为重要。其次,SSL/TLS有助于与用户建立信任。当用户看到网站使用SSL/TLS保护时,他们可以确信自己的数据得到了安全处理。最后,使用SSL/TLS还可以带来SEO优势,因为搜索引擎通常会优先考虑使用安全连接的网站。

如何为Node.js生成自签名证书?

可以使用OpenSSL为Node.js生成自签名证书。首先,您需要在系统上安装OpenSSL。安装完成后,您可以使用以下命令生成自签名证书:

Bash

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

这将创建一个新的RSA密钥对和一个有效期为365天的证书。-keyout选项指定要写入新创建的私钥的文件名,-out选项指定证书的输出文件名。

如何将创建的SSL/TLS证书与我的Node.js服务器一起使用?

生成SSL/TLS证书后,您可以将其添加到服务器配置中,以便与Node.js服务器一起使用。这可以通过 https模块的 createServer方法来实现,该方法接受一个选项对象和一个请求监听器。选项对象应该包含您的证书和私钥,如下所示:

JavaScript

const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem')
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end('hello world\n');
}).listen(8000);

这将创建一个使用您的SSL/TLS证书的新HTTPS服务器。

SSL和TLS之间有什么区别?

SSL(安全套接字层)和TLS(传输层安全性)都是旨在通过网络提供安全通信的加密协议。虽然它们经常互换使用,但它们之间存在一些关键区别。SSL是两种协议中较早的一种,由于已知的安全漏洞,已被大量弃用。TLS是SSL的后继者,提供了更高的安全性和性能。通常,当人们提到SSL/TLS时,他们通常指的是TLS。

如何在Node.js中将HTTP流量重定向到HTTPS?

将HTTP流量重定向到HTTPS可以通过创建一个HTTP服务器来实现,该服务器监听传入连接并将其重定向到HTTPS服务器。可以使用 http模块的 createServer方法完成此操作,如下所示:

JavaScript

const http = require('http');

http.createServer((req, res) => {
  res.writeHead(301, { 'Location': 'https://' + req.headers['host'] + req.url });
  res.end();
}).listen(80);

这将创建一个新的HTTP服务器,该服务器监听端口80,并将所有传入连接重定向到等效的HTTPS URL。

如何验证我的Node.js服务器的SSL/TLS配置?

您可以使用在线工具(例如SSL Labs的SSL服务器测试)来验证Node.js服务器的SSL/TLS配置。此工具将对任何SSL Web服务器的配置进行深入分析,并提供包含服务器证书、协议支持、密码强度等信息的详细报告。

如果我在Node.js中遇到SSL/TLS错误该怎么办?

如果您在Node.js中遇到SSL/TLS错误,第一步是尝试理解错误消息。错误消息通常会提供一些线索,帮助您判断问题所在。常见问题包括证书问题(例如证书已过期或不受信任)或服务器配置问题。如果您无法自行解决问题,请考虑向Node.js社区或专业人士寻求帮助。

如何更新我的Node.js服务器上的SSL/TLS证书?

更新Node.js服务器上的SSL/TLS证书需要生成新证书(或从证书颁发机构获取证书),然后更新服务器配置以使用新证书。新证书到位后,您需要重新启动服务器才能使更改生效。

我可以使用Let's Encrypt为我的Node.js服务器获取免费的SSL/TLS证书吗?

是的,Let's Encrypt是一个免费、自动化且开放的证书颁发机构,可用于获取SSL/TLS证书。他们提供了一个名为Certbot的工具,可以自动执行证书的获取和安装过程。安装后,Certbot还可以在证书到期前自动续订。

什么是完美前向保密性以及如何在Node.js中启用它?

完美前向保密(PFS)是安全通信协议的一种特性,它允许长期密钥的泄露不会危及过去的会话密钥。这意味着即使服务器的私钥被泄露,过去的通信仍然是安全的。在Node.js中,可以通过将服务器配置为使用一组支持PFS的密码套件(例如ECDHE或DHE密钥交换算法提供的密码套件)来启用PFS。

标签

有用
分享
无用
反馈
返回顶部
0 个回答
26 次浏览
立即加入,帮您快速选购适合您的SSL数字证书 申请SSL证书
免费SSL证书_专业SSL证书申请_HTTPS加密【TopSSL】
免费SSL证书永久生成
微信公众号二维码 扫一扫在线咨询
关注 TopSSL 公众号, RSS订阅 SSL资讯与技术支持

2004-2025 © 北京传诚信  版权所有 | TopSSL提供免费SSL证书SSL证书申请轻松实现HTTPS加密! 北京市朝阳区鹏景阁大厦16层

技术协助:wo@topssl.cn 企业咨询:vip@topssl.cn