TLS (SSL)#

稳定性:2 - 稳定

node:tls 模块提供了基于 OpenSSL 构建的传输层安全性 (TLS) 和安全套接字层 (SSL) 协议的实现。可以通过以下方式访问该模块:

import tls from 'node:tls';
const tls = require('node:tls');

确定加密支持是否不可用#

Node.js 在构建时可能未包含对 node:crypto 模块的支持。在这种情况下,尝试从 tls 导入或调用 require('node:tls') 将会抛出错误。

使用 CommonJS 时,抛出的错误可以使用 try/catch 捕获。

let tls;
try {
  tls = require('node:tls');
} catch (err) {
  console.error('tls support is disabled!');
}

当使用词法 ESM import 关键字时,只有在尝试加载模块*之前*注册了 process.on('uncaughtException') 的处理程序(例如,使用预加载模块),才能捕获该错误。

使用 ESM 时,如果代码有可能在未启用加密支持的 Node.js 版本上运行,请考虑使用 import() 函数,而不是词法 import 关键字。

let tls;
try {
  tls = await import('node:tls');
} catch (err) {
  console.error('tls support is disabled!');
}

TLS/SSL 概念#

TLS/SSL 是一组依赖于公钥基础设施 (PKI) 的协议,用于在客户端和服务器之间实现安全通信。在大多数常见情况下,每台服务器都必须拥有一个私钥。

私钥可以通过多种方式生成。以下示例展示了使用 OpenSSL 命令行界面生成 2048 位 RSA 私钥的方法:

openssl genrsa -out ryans-key.pem 2048

使用 TLS/SSL 时,所有服务器(以及部分客户端)都必须拥有一个证书。证书是对应于私钥的公钥,并由证书颁发机构 (CA) 或私钥的所有者进行数字签名(此类证书称为“自签名证书”)。获取证书的第一步是创建证书签名请求 (CSR) 文件。

可以使用 OpenSSL 命令行界面为私钥生成 CSR:

openssl req -new -sha256 -key ryans-key.pem -out ryans-csr.pem

CSR 文件生成后,可以将其发送给证书颁发机构进行签名,或者用于生成自签名证书。

以下示例展示了如何使用 OpenSSL 命令行界面创建自签名证书:

openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem

证书生成后,可用于生成 .pfx.p12 文件:

openssl pkcs12 -export -in ryans-cert.pem -inkey ryans-key.pem \
      -certfile ca-cert.pem -out ryans.pfx

其中:

  • in:已签名的证书。
  • inkey:关联的私钥。
  • certfile:将所有证书颁发机构 (CA) 证书连接成单个文件,例如 cat ca1-cert.pem ca2-cert.pem > ca-cert.pem

完美前向保密#

术语前向保密完美前向保密描述了密钥协商(即密钥交换)方法的一种特性。即服务器和客户端密钥用于协商专门且仅用于当前通信会话的临时新密钥。实际上,这意味着即使服务器的私钥被泄露,窃听者也只有在设法获取专门为该会话生成的密钥对的情况下,才能解密通信。

通过在每次 TLS/SSL 握手时随机生成用于密钥协商的密钥对(与对所有会话使用相同的密钥相反),可以实现完美前向保密。实现此技术的方法称为“临时” (ephemeral)。

目前有两种常用的方法来实现完美前向保密(注意在传统缩写后添加了字母 "E"):

  • ECDHE:椭圆曲线 Diffie-Hellman 密钥协商协议的临时版本。
  • DHE:Diffie-Hellman 密钥协商协议的临时版本。

默认启用使用 ECDHE 的完美前向保密。创建 TLS 服务器时可以使用 ecdhCurve 选项来自定义支持的 ECDH 曲线列表。更多信息请参见 tls.createServer()

DHE 默认禁用,但可以通过将 dhparam 选项设置为 'auto' 来与 ECDHE 一起启用。也支持自定义 DHE 参数,但不建议这样做,建议优先使用自动选择的、众所周知的参数。

完美前向保密在 TLSv1.2 之前是可选的。从 TLSv1.3 开始,总是使用 (EC)DHE(仅 PSK 连接除外)。

ALPN 和 SNI#

ALPN(应用层协议协商扩展)和 SNI(服务器名称指示)是 TLS 握手扩展。

  • ALPN:允许单个 TLS 服务器用于多种协议(HTTP、HTTP/2)。
  • SNI:允许单个 TLS 服务器用于具有不同证书的多个主机名。

预共享密钥 (PSK)#

TLS-PSK 支持作为常规基于证书的身份验证的替代方案提供。它使用预共享密钥而不是证书来验证 TLS 连接,提供双向身份验证。TLS-PSK 与公钥基础设施并非互斥。客户端和服务器可以同时容纳两者,并在常规密码协商步骤中选择其中任何一个。

TLS-PSK 仅在有手段与每台连接机器安全共享密钥时才是好的选择,因此它不能取代大多数 TLS 用途的公钥基础设施 (PKI)。OpenSSL 中的 TLS-PSK 实现近年来出现过许多安全漏洞,主要是因为它仅被少数应用程序使用。在切换到 PSK 密码之前,请考虑所有替代解决方案。生成 PSK 时,使用足够的熵至关重要,如 RFC 4086 中所讨论。从密码或其他低熵源派生共享密钥是不安全的。

PSK 密码默认禁用,因此使用 TLS-PSK 需要通过 ciphers 选项显式指定密码套件。可用密码列表可以通过 openssl ciphers -v 'PSK' 获取。所有 TLS 1.3 密码都符合 PSK 条件,可通过 openssl ciphers -v -s -tls1_3 -psk 获取。在客户端连接上,应传递自定义的 checkServerIdentity,因为默认值在没有证书的情况下会失败。

根据 RFC 4279,必须支持长度不超过 128 字节的 PSK 标识和长度不超过 64 字节的 PSK。从 OpenSSL 1.1.0 开始,最大标识大小为 128 字节,最大 PSK 长度为 256 字节。

由于底层 OpenSSL API 的限制,当前的实现不支持异步 PSK 回调。

要使用 TLS-PSK,客户端和服务器必须指定 pskCallback 选项,这是一个返回要使用的 PSK(必须与所选密码的摘要兼容)的函数。

它将首先在客户端调用:

  • hint <string> 可选消息,由服务器发送以帮助客户端决定在协商期间使用哪个身份。如果使用 TLS 1.3,则始终为 null
  • 返回:<Object>,格式为 { psk: <Buffer|TypedArray|DataView>, identity: <string> }null

然后在服务器端:

返回值为 null 会停止协商过程并向对方发送 unknown_psk_identity 警报消息。如果服务器希望隐藏 PSK 标识未知的事实,回调必须提供一些随机数据作为 psk,以使连接在协商完成前因 decrypt_error 而失败。

客户端发起重协商攻击缓解#

TLS 协议允许客户端重协商 TLS 会话的某些方面。遗憾的是,会话重协商需要服务器端不成比例的资源,使其成为拒绝服务攻击的潜在向量。

为了降低风险,重协商限制为每十分钟三次。当超过此阈值时,tls.TLSSocket 实例上会触发 'error' 事件。这些限制是可配置的:

  • tls.CLIENT_RENEG_LIMIT <number> 指定重协商请求的次数。默认值: 3
  • tls.CLIENT_RENEG_WINDOW <number> 指定重协商窗口的时间(以秒为单位)。默认值: 600(10 分钟)。

如果不完全理解其影响和风险,不应修改默认的重协商限制。

TLSv1.3 不支持重协商。

会话恢复#

建立 TLS 会话可能相对缓慢。通过保存并随后重用会话状态,可以加快此过程。有几种机制可以实现此目的,在此从最旧到最新(且首选)进行讨论。

会话标识符#

服务器为新连接生成唯一 ID 并将其发送给客户端。客户端和服务器保存会话状态。重新连接时,客户端发送其已保存会话状态的 ID,如果服务器也拥有该 ID 的状态,则可以同意使用它。否则,服务器将创建一个新会话。有关更多信息,请参见 RFC 2246 第 23 页和第 30 页。

在进行 HTTPS 请求时,大多数 Web 浏览器都支持使用会话标识符进行恢复。

对于 Node.js,客户端等待 'session' 事件来获取会话数据,并将数据提供给后续 tls.connect()session 选项以重用会话。服务器必须实现 'newSession''resumeSession' 事件的处理程序,以使用会话 ID 作为查找键来保存和恢复会话数据,从而重用会话。要在负载均衡器或集群工作线程之间重用会话,服务器必须在其会话处理程序中使用共享会话缓存(例如 Redis)。

会话票据#

服务器加密整个会话状态并将其作为“票据”发送给客户端。重新连接时,状态在初始连接中发送给服务器。这种机制避免了对服务器端会话缓存的需要。如果服务器因任何原因(解密失败、过旧等)不使用该票据,它将创建一个新会话并发送一个新票据。有关更多信息,请参见 RFC 5077

在进行 HTTPS 请求时,许多 Web 浏览器都普遍支持使用会话票据进行恢复。

对于 Node.js,客户端使用与会话标识符恢复相同的 API 来进行会话票据恢复。为了进行调试,如果 tls.TLSSocket.getTLSTicket() 返回一个值,则会话数据包含一个票据,否则包含客户端侧的会话状态。

对于 TLSv1.3,请注意服务器可能会发送多个票据,从而导致多次 'session' 事件,更多信息请参见 'session'

单进程服务器不需要特定的实现来使用会话票据。要在服务器重启或负载均衡器之间使用会话票据,所有服务器必须具有相同的票据密钥。内部有三个 16 字节的密钥,但为方便起见,tls API 将它们公开为单个 48 字节的缓冲区。

可以通过在一个服务器实例上调用 server.getTicketKeys() 获取票据密钥并分发它们,但更合理的做法是安全地生成 48 字节的安全随机数据,并使用 tls.createServer()ticketKeys 选项设置它们。密钥应定期重新生成,服务器的密钥可以使用 server.setTicketKeys() 重置。

会话票据密钥是加密密钥,必须安全存储。在 TLS 1.2 及以下版本中,如果它们被泄露,则所有使用这些密钥加密的票据的会话都可以被解密。它们不应存储在磁盘上,并且应定期重新生成。

如果客户端宣传对票据的支持,服务器将发送它们。服务器可以通过在 secureOptions 中提供 require('node:constants').SSL_OP_NO_TICKET 来禁用票据。

会话标识符和会话票据都会超时,导致服务器创建新会话。超时时间可以通过 tls.createServer()sessionTimeout 选项配置。

对于所有机制,当恢复失败时,服务器将创建新会话。由于恢复会话失败不会导致 TLS/HTTPS 连接失败,因此很容易忽略不必要的糟糕 TLS 性能。OpenSSL CLI 可用于验证服务器是否正在恢复会话。例如,对 openssl s_client 使用 -reconnect 选项:

openssl s_client -connect localhost:443 -reconnect

通读调试输出。第一个连接应该显示“New”,例如:

New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256

后续连接应该显示“Reused”,例如:

Reused, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256

修改默认 TLS 密码套件#

Node.js 构建时包含了一套默认的已启用和已禁用的 TLS 密码。此默认密码列表可以在构建 Node.js 时配置,以允许发行版提供自己的默认列表。

可以使用以下命令显示默认密码套件:

node -p crypto.constants.defaultCoreCipherList | tr ':' '\n'
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_GCM_SHA256
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-AES256-GCM-SHA384
DHE-RSA-AES128-GCM-SHA256
ECDHE-RSA-AES128-SHA256
DHE-RSA-AES128-SHA256
ECDHE-RSA-AES256-SHA384
DHE-RSA-AES256-SHA384
ECDHE-RSA-AES256-SHA256
DHE-RSA-AES256-SHA256
HIGH
!aNULL
!eNULL
!EXPORT
!DES
!RC4
!MD5
!PSK
!SRP
!CAMELLIA

此默认设置可以使用 --tls-cipher-list 命令行开关(直接使用,或通过 NODE_OPTIONS 环境变量)完全替换。例如,以下设置使 ECDHE-RSA-AES128-GCM-SHA256:!RC4 成为默认 TLS 密码套件:

node --tls-cipher-list='ECDHE-RSA-AES128-GCM-SHA256:!RC4' server.js

export NODE_OPTIONS=--tls-cipher-list='ECDHE-RSA-AES128-GCM-SHA256:!RC4'
node server.js

要验证,请使用以下命令显示设置的密码列表,注意 defaultCoreCipherListdefaultCipherList 之间的区别:

node --tls-cipher-list='ECDHE-RSA-AES128-GCM-SHA256:!RC4' -p crypto.constants.defaultCipherList | tr ':' '\n'
ECDHE-RSA-AES128-GCM-SHA256
!RC4

defaultCoreCipherList 列表是在编译时设置的,而 defaultCipherList 是在运行时设置的。

要在运行时修改默认密码套件,请修改 tls.DEFAULT_CIPHERS 变量,这必须在监听任何套接字之前执行,它不会影响已经打开的套接字。例如:

// Remove Obsolete CBC Ciphers and RSA Key Exchange based Ciphers as they don't provide Forward Secrecy
tls.DEFAULT_CIPHERS +=
  ':!ECDHE-RSA-AES128-SHA:!ECDHE-RSA-AES128-SHA256:!ECDHE-RSA-AES256-SHA:!ECDHE-RSA-AES256-SHA384' +
  ':!ECDHE-ECDSA-AES128-SHA:!ECDHE-ECDSA-AES128-SHA256:!ECDHE-ECDSA-AES256-SHA:!ECDHE-ECDSA-AES256-SHA384' +
  ':!kRSA';

默认值还可以基于每个客户端或服务器进行替换,使用来自 tls.createSecureContext()ciphers 选项,该选项也可在 tls.createServer()tls.connect() 以及创建新的 tls.TLSSocket 时使用。

密码列表可以包含 TLSv1.3 密码套件名称(以 'TLS_' 开头)和 TLSv1.2 及以下版本密码套件规范的混合。TLSv1.2 密码支持旧式规范格式,有关详细信息,请咨询 OpenSSL 密码列表格式文档,但这些规范适用于 TLSv1.3 密码。TLSv1.3 套件只能通过在密码列表中包含其全名来启用。例如,它们不能通过使用旧式 TLSv1.2 'EECDH''!EECDH' 规范来启用或禁用。

尽管 TLSv1.3 和 TLSv1.2 密码套件的相对顺序如何,TLSv1.3 协议比 TLSv1.2 安全得多,并且如果握手表明它受支持,并且启用了任何 TLSv1.3 密码套件,它将始终优先于 TLSv1.2 被选择。

Node.js 中包含的默认密码套件经过仔细选择,以反映当前的安全最佳实践和风险缓解。更改默认密码套件可能会对应用程序的安全性产生重大影响。仅在绝对必要时才应使用 --tls-cipher-list 开关和 ciphers 选项。

默认密码套件优先选择 GCM 密码以匹配 Chrome 的“现代加密”设置,并且还优先选择 ECDHE 和 DHE 密码以实现完美前向保密,同时提供一些向后兼容性。

依赖不安全和已弃用的 RC4 或基于 DES 的密码的旧客户端(如 Internet Explorer 6)无法使用默认配置完成握手过程。如果必须支持这些客户端,TLS 建议可能会提供兼容的密码套件。有关格式的更多详细信息,请参见 OpenSSL 密码列表格式文档。

只有五个 TLSv1.3 密码套件:

  • 'TLS_AES_256_GCM_SHA384'
  • 'TLS_CHACHA20_POLY1305_SHA256'
  • 'TLS_AES_128_GCM_SHA256'
  • 'TLS_AES_128_CCM_SHA256'
  • 'TLS_AES_128_CCM_8_SHA256'

前三个默认启用。两个基于 CCM 的套件受 TLSv1.3 支持,因为它们在受限系统上可能性能更高,但由于它们提供的安全性较低,默认情况下未启用。

OpenSSL 安全级别#

OpenSSL 库强制执行安全级别以控制加密操作的最低可接受安全级别。OpenSSL 的安全级别范围从 0 到 5,每个级别都施加更严格的安全要求。默认安全级别为 2,通常适用于大多数现代应用程序。但是,某些旧功能和协议(例如 TLSv1)需要较低的安全级别 (SECLEVEL=0) 才能正常工作。有关更详细的信息,请参阅 OpenSSL 关于安全级别的文档

设置安全级别#

要在 Node.js 应用程序中调整安全级别,可以在密码字符串中包含 @SECLEVEL=X,其中 X 是所需的安全级别。例如,要在使用默认 OpenSSL 密码列表时将安全级别设置为 0,可以使用:

import { createServer, connect } from 'node:tls';
const port = 443;

createServer({ ciphers: 'DEFAULT@SECLEVEL=0', minVersion: 'TLSv1' }, function(socket) {
  console.log('Client connected with protocol:', socket.getProtocol());
  socket.end();
  this.close();
})
.listen(port, () => {
  connect(port, { ciphers: 'DEFAULT@SECLEVEL=0', maxVersion: 'TLSv1' });
});
const { createServer, connect } = require('node:tls');
const port = 443;

createServer({ ciphers: 'DEFAULT@SECLEVEL=0', minVersion: 'TLSv1' }, function(socket) {
  console.log('Client connected with protocol:', socket.getProtocol());
  socket.end();
  this.close();
})
.listen(port, () => {
  connect(port, { ciphers: 'DEFAULT@SECLEVEL=0', maxVersion: 'TLSv1' });
});

此方法将安全级别设置为 0,允许使用旧功能,同时仍利用默认的 OpenSSL 密码。

使用 --tls-cipher-list#

您还可以使用 --tls-cipher-list=DEFAULT@SECLEVEL=X 从命令行设置安全级别和密码,如 修改默认 TLS 密码套件中所述。但是,通常不建议使用命令行选项来设置密码,最好在应用程序代码内为单个上下文配置密码,因为这种方法提供了更细致的控制,并降低了全局降低安全级别的风险。

X509 证书错误代码#

多个函数可能会因 OpenSSL 报告的证书错误而失败。在这种情况下,该函数通过其回调提供一个 <Error>,该错误具有 code 属性,可以取以下值之一:

  • 'UNABLE_TO_GET_ISSUER_CERT':无法获取颁发者证书。
  • 'UNABLE_TO_GET_CRL':无法获取证书 CRL。
  • 'UNABLE_TO_DECRYPT_CERT_SIGNATURE':无法解密证书签名。
  • 'UNABLE_TO_DECRYPT_CRL_SIGNATURE':无法解密 CRL 签名。
  • 'UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY':无法解码颁发者公钥。
  • 'CERT_SIGNATURE_FAILURE':证书签名失败。
  • 'CRL_SIGNATURE_FAILURE':CRL 签名失败。
  • 'CERT_NOT_YET_VALID':证书尚未生效。
  • 'CERT_HAS_EXPIRED':证书已过期。
  • 'CRL_NOT_YET_VALID':CRL 尚未生效。
  • 'CRL_HAS_EXPIRED':CRL 已过期。
  • 'ERROR_IN_CERT_NOT_BEFORE_FIELD':证书 notBefore 字段格式错误。
  • 'ERROR_IN_CERT_NOT_AFTER_FIELD':证书 notAfter 字段格式错误。
  • 'ERROR_IN_CRL_LAST_UPDATE_FIELD':CRL lastUpdate 字段格式错误。
  • 'ERROR_IN_CRL_NEXT_UPDATE_FIELD':CRL nextUpdate 字段格式错误。
  • 'OUT_OF_MEM':内存不足。
  • 'DEPTH_ZERO_SELF_SIGNED_CERT':自签名证书。
  • 'SELF_SIGNED_CERT_IN_CHAIN':证书链中存在自签名证书。
  • 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY':无法在本地获取颁发者证书。
  • 'UNABLE_TO_VERIFY_LEAF_SIGNATURE':无法验证第一个证书。
  • 'CERT_CHAIN_TOO_LONG':证书链太长。
  • 'CERT_REVOKED':证书已吊销。
  • 'INVALID_CA':无效的 CA 证书。
  • 'PATH_LENGTH_EXCEEDED':路径长度约束超出。
  • 'INVALID_PURPOSE':不受支持的证书目的。
  • 'CERT_UNTRUSTED':证书不受信任。
  • 'CERT_REJECTED':证书被拒绝。
  • 'HOSTNAME_MISMATCH':主机名不匹配。

当发生如 UNABLE_TO_VERIFY_LEAF_SIGNATUREDEPTH_ZERO_SELF_SIGNED_CERTUNABLE_TO_GET_ISSUER_CERT 等证书错误时,Node.js 会附加一条提示,建议如果根 CA 已在本地安装,请尝试使用 --use-system-ca 标志运行,以引导开发人员使用安全的解决方案,从而防止不安全的变通方法。

类:tls.Server#

使用 TLS 或 SSL 接受加密连接。

事件:'connection'#

当建立新的 TCP 流时(在 TLS 握手开始之前)会触发此事件。socket 通常是 net.Socket 类型的对象,但与通过 net.Server 'connection' 事件创建的套接字不同,它不会接收事件。通常用户不需要访问此事件。

此事件也可以由用户显式触发,以将连接注入 TLS 服务器。在这种情况下,可以传递任何 Duplex 流。

事件:'keylog'#

  • line <Buffer> ASCII 文本行,采用 NSS SSLKEYLOGFILE 格式。
  • tlsSocket <tls.TLSSocket> 生成该事件的 tls.TLSSocket 实例。

当此服务器的连接生成或接收到密钥材料时,会触发 keylog 事件(通常在握手完成之前,但不一定)。此密钥材料可以存储以供调试,因为它允许解密捕获的 TLS 流量。它可能为每个套接字触发多次。

一个典型的用例是将接收到的行追加到一个公共文本文件中,该文件随后被软件(如 Wireshark)用来解密流量:

const logFile = fs.createWriteStream('/tmp/ssl-keys.log', { flags: 'a' });
// ...
server.on('keylog', (line, tlsSocket) => {
  if (tlsSocket.remoteAddress !== '...')
    return; // Only log keys for a particular IP
  logFile.write(line);
});

事件:'newSession'#

当创建新的 TLS 会话时,会触发 'newSession' 事件。这可用于将会话存储在外部存储中。数据应提供给 'resumeSession' 回调。

调用时,监听器回调会收到三个参数:

  • sessionId <Buffer> TLS 会话标识符。
  • sessionData <Buffer> TLS 会话数据。
  • callback <Function> 一个无参数的回调函数,必须调用它才能通过安全连接发送或接收数据。

监听此事件仅对添加事件监听器之后建立的连接产生影响。

事件:'OCSPRequest'#

当客户端发送证书状态请求时,会触发 'OCSPRequest' 事件。调用时,监听器回调会收到三个参数:

  • certificate <Buffer> 服务器证书。
  • issuer <Buffer> 颁发者的证书。
  • callback <Function> 必须调用的回调函数,用于提供 OCSP 请求的结果。

可以解析服务器当前的证书以获取 OCSP URL 和证书 ID;获取 OCSP 响应后,调用 callback(null, resp),其中 resp 是包含 OCSP 响应的 Buffer 实例。certificateissuer 都是主要证书和颁发者证书的 Buffer DER 表示。这些可用于获取 OCSP 证书 ID 和 OCSP 端点 URL。

或者,可以调用 callback(null, null),表示没有 OCSP 响应。

调用 callback(err) 将导致调用 socket.destroy(err)

OCSP 请求的典型流程如下:

  1. 客户端连接到服务器并发送 'OCSPRequest'(通过 ClientHello 中的状态信息扩展)。
  2. 服务器接收请求并触发 'OCSPRequest' 事件,如果已注册,则调用监听器。
  3. 服务器从 certificateissuer 中提取 OCSP URL,并对 CA 执行 OCSP 请求
  4. 服务器从 CA 接收 'OCSPResponse' 并通过 callback 参数将其发回给客户端。
  5. 客户端验证响应并销毁套接字或执行握手。

如果证书是自签名的或者颁发者不在根证书列表中,则 issuer 可能为 null。(建立 TLS 连接时可以通过 ca 选项提供颁发者。)

监听此事件仅对添加事件监听器之后建立的连接产生影响。

可以使用像 asn1.js 这样的 npm 模块来解析证书。

事件:'resumeSession'#

当客户端请求恢复之前的 TLS 会话时,会触发 'resumeSession' 事件。调用时,监听器回调会收到两个参数:

  • sessionId <Buffer> TLS 会话标识符。
  • callback <Function> 当先前会话已恢复时要调用的回调函数:callback([err[, sessionData]])

事件监听器应使用给定的 sessionId 在外部存储中执行对 'newSession' 事件处理程序所保存的 sessionData 的查找。如果找到,调用 callback(null, sessionData) 以恢复会话。如果未找到,则无法恢复会话。必须在不带 sessionData 的情况下调用 callback(),以便握手可以继续并可以创建新会话。可以调用 callback(err) 来终止传入连接并销毁套接字。

监听此事件仅对添加事件监听器之后建立的连接产生影响。

以下示例展示了恢复 TLS 会话:

const tlsSessionStore = {};
server.on('newSession', (id, data, cb) => {
  tlsSessionStore[id.toString('hex')] = data;
  cb();
});
server.on('resumeSession', (id, cb) => {
  cb(null, tlsSessionStore[id.toString('hex')] || null);
});

事件:'secureConnection'#

在新的连接握手过程成功完成后,会触发 'secureConnection' 事件。调用时,监听器回调会收到单个参数:

tlsSocket.authorized 属性是一个 boolean 值,指示客户端是否已由为服务器提供的证书颁发机构之一验证。如果 tlsSocket.authorizedfalse,则设置 socket.authorizationError 以描述授权失败的原因。根据 TLS 服务器的设置,未经授权的连接仍可能被接受。

tlsSocket.alpnProtocol 属性是一个字符串,包含所选的 ALPN 协议。当 ALPN 没有选定的协议(因为客户端或服务器未发送 ALPN 扩展)时,tlsSocket.alpnProtocol 等于 false

tlsSocket.servername 属性是一个字符串,包含通过 SNI 请求的服务器名称。

事件:'tlsClientError'#

当在安全连接建立之前发生错误时,会触发 'tlsClientError' 事件。调用时,监听器回调会收到两个参数:

  • exception <Error> 描述错误的 Error 对象。
  • tlsSocket <tls.TLSSocket> 错误源自的 tls.TLSSocket 实例。

server.addContext(hostname, context)#

server.addContext() 方法添加了一个安全上下文,如果客户端请求的 SNI 名称与提供的 hostname(或通配符)匹配,则会使用该上下文。

当有多个匹配的上下文时,将使用最近添加的一个。

server.address()#

返回操作系统报告的服务器绑定地址、地址族名称和端口。更多信息请参见 net.Server.address()

server.close([callback])#

  • callback <Function> 将注册以监听服务器实例 'close' 事件的监听器回调。
  • 返回:<tls.Server>

server.close() 方法停止服务器接受新连接。

此函数异步执行。当服务器不再有打开的连接时,将触发 'close' 事件。

server.getTicketKeys()#

  • 返回:<Buffer> 包含会话票据密钥的 48 字节缓冲区。

返回会话票据密钥。

更多信息请参见 会话恢复

server.listen()#

启动服务器监听加密连接。此方法等同于 net.Serverserver.listen()

server.setSecureContext(options)#

server.setSecureContext() 方法替换现有服务器的安全上下文。到服务器的现有连接不会中断。

server.setTicketKeys(keys)#

设置会话票据密钥。

对票据密钥的更改仅对未来的服务器连接有效。现有的或当前待处理的服务器连接将使用以前的密钥。

更多信息请参见 会话恢复

类:tls.TLSSocket#

对写入的数据进行透明加密,并执行所有必需的 TLS 协商。

tls.TLSSocket 的实例实现了双工 Stream 接口。

返回 TLS 连接元数据的方法(例如 tls.TLSSocket.getPeerCertificate())仅在连接打开时返回数据。

new tls.TLSSocket(socket[, options])#

  • socket <net.Socket> | <stream.Duplex> 在服务器端,可以是任何 Duplex 流。在客户端,必须是 net.Socket 的实例(对于客户端上的通用 Duplex 流支持,必须使用 tls.connect())。
  • options <Object>
  • enableTrace:参见 tls.createServer()
  • isServer:SSL/TLS 协议是非对称的,TLSSocket 必须知道它们是作为服务器还是客户端运行。如果为 true,TLS 套接字将实例化为服务器。默认值: false
  • server <net.Server> net.Server 实例。
  • requestCert:是否通过请求证书来验证远程对等方。客户端始终请求服务器证书。服务器(isServer 为 true)可以将 requestCert 设置为 true 以请求客户端证书。
  • rejectUnauthorized:参见 tls.createServer()
  • ALPNProtocols:参见 tls.createServer()
  • SNICallback:参见 tls.createServer()
  • ALPNCallback:参见 tls.createServer()
  • session <Buffer> 包含 TLS 会话的 Buffer 实例。
  • requestOCSP <boolean> 如果为 true,则指定 OCSP 状态请求扩展将被添加到客户端 hello 中,并且在建立安全通信之前将在套接字上触发 'OCSPResponse' 事件。
  • secureContext:使用 tls.createSecureContext() 创建的 TLS 上下文对象。如果提供 secureContext,则通过将整个 options 对象传递给 tls.createSecureContext() 来创建一个。
  • ...:如果缺少 secureContext 选项,则使用 tls.createSecureContext() 的选项。否则,它们将被忽略。

从现有的 TCP 套接字构建一个新的 tls.TLSSocket 对象。

事件:'keylog'#

  • line <Buffer> ASCII 文本行,采用 NSS SSLKEYLOGFILE 格式。

当套接字生成或接收到密钥材料时,会在 tls.TLSSocket 上触发 keylog 事件。此密钥材料可以存储以供调试,因为它允许解密捕获的 TLS 流量。它可能在握手完成之前或之后触发多次。

一个典型的用例是将接收到的行追加到一个公共文本文件中,该文件随后被软件(如 Wireshark)用来解密流量:

const logFile = fs.createWriteStream('/tmp/ssl-keys.log', { flags: 'a' });
// ...
tlsSocket.on('keylog', (line) => logFile.write(line));

事件:'OCSPResponse'#

如果在创建 tls.TLSSocket 时设置了 requestOCSP 选项并且收到了 OCSP 响应,则会触发 'OCSPResponse' 事件。调用时,监听器回调会收到单个参数:

  • response <Buffer> 服务器的 OCSP 响应。

通常,response 是来自服务器 CA 的数字签名对象,包含有关服务器证书吊销状态的信息。

事件:'secure'#

在 TLS 握手成功完成且已建立安全连接后,会触发 'secure' 事件。

此事件在客户端和服务器 <tls.TLSSocket> 实例上触发,包括使用 new tls.TLSSocket() 构造函数创建的套接字。

事件:'secureConnect'#

在新的连接握手过程成功完成后,会触发 'secureConnect' 事件。无论服务器证书是否已授权,监听器回调都将被调用。客户端有责任检查 tlsSocket.authorized 属性以确定服务器证书是否由指定的 CA 之一签名。如果 tlsSocket.authorized === false,则可以通过检查 tlsSocket.authorizationError 属性找到错误。如果使用了 ALPN,可以检查 tlsSocket.alpnProtocol 属性以确定协商的协议。

使用 new tls.TLSSocket() 构造函数创建 <tls.TLSSocket> 时,不会触发 'secureConnect' 事件。

事件:'session'#

当有新的会话或 TLS 票据可用时,会在客户端 tls.TLSSocket 上触发 'session' 事件。这可能在握手完成之前或之后,具体取决于协商的 TLS 协议版本。此事件不会在服务器上触发,或者如果未创建新会话(例如连接已恢复),也不会触发。对于某些 TLS 协议版本,该事件可能会被触发多次,在这种情况下,所有会话都可以用于恢复。

在客户端上,可以将 session 提供给 tls.connect()session 选项以恢复连接。

更多信息请参见 会话恢复

对于 TLSv1.2 及以下版本,可以在握手完成后调用 tls.TLSSocket.getSession()。对于 TLSv1.3,协议只允许基于票据的恢复,会发送多个票据,并且在握手完成后才会发送票据。因此,必须等待 'session' 事件以获取可恢复的会话。应用程序应使用 'session' 事件而不是 getSession(),以确保它们适用于所有 TLS 版本。仅期望获取或使用一个会话的应用程序应仅监听一次此事件:

tlsSocket.once('session', (session) => {
  // The session can be used immediately or later.
  tls.connect({
    session: session,
    // Other connect options...
  });
});

tlsSocket.address()#

返回操作系统报告的底层套接字的绑定 addressfamily 名称和 port{ port: 12346, family: 'IPv4', address: '127.0.0.1' }

tlsSocket.authorizationError#

返回对等方证书未被验证的原因。此属性仅在 tlsSocket.authorized === false 时设置。

tlsSocket.authorized#

如果对等方证书是由创建 tls.TLSSocket 实例时指定的 CA 之一签名的,则此属性为 true,否则为 false

tlsSocket.disableRenegotiation()#

禁用此 TLSSocket 实例的 TLS 重协商。一旦调用,重协商尝试将触发 TLSSocket 上的 'error' 事件。

tlsSocket.enableTrace()#

启用后,TLS 数据包跟踪信息将被写入 stderr。这可用于调试 TLS 连接问题。

输出格式与 openssl s_client -traceopenssl s_server -trace 的输出完全相同。虽然它是由 OpenSSL 的 SSL_trace() 函数生成的,但该格式未记录,可能会在不通知的情况下更改,不应依赖它。

tlsSocket.encrypted#

始终返回 true。这可用于区分 TLS 套接字和常规 net.Socket 实例。

tlsSocket.exportKeyingMaterial(length, label[, context])#

密钥材料用于验证以防止网络协议中不同种类的攻击,例如在 IEEE 802.1X 的规范中。

示例

const keyingMaterial = tlsSocket.exportKeyingMaterial(
  128,
  'client finished');

/*
 Example return value of keyingMaterial:
 <Buffer 76 26 af 99 c5 56 8e 42 09 91 ef 9f 93 cb ad 6c 7b 65 f8 53 f1 d8 d9
    12 5a 33 b8 b5 25 df 7b 37 9f e0 e2 4f b8 67 83 a3 2f cd 5d 41 42 4c 91
    74 ef 2c ... 78 more bytes>
*/

有关更多信息,请参见 OpenSSL SSL_export_keying_material 文档。

tlsSocket.getCertificate()#

返回表示本地证书的对象。返回的对象具有对应于证书字段的一些属性。

有关证书结构的示例,请参见 tls.TLSSocket.getPeerCertificate()

如果没有本地证书,将返回一个空对象。如果套接字已被销毁,将返回 null

tlsSocket.getCipher()#

返回包含有关协商密码套件信息的对象。

例如,具有 AES256-SHA 密码的 TLSv1.2 协议:

{
    "name": "AES256-SHA",
    "standardName": "TLS_RSA_WITH_AES_256_CBC_SHA",
    "version": "SSLv3"
}

有关更多信息,请参见 SSL_CIPHER_get_name

tlsSocket.getEphemeralKeyInfo()#

返回一个对象,表示客户端连接上 完美前向保密 中临时密钥交换参数的类型、名称和大小。当密钥交换不是临时时,它返回一个空对象。由于这仅在客户端套接字上受支持;如果在服务器套接字上调用,则返回 null。支持的类型是 'DH''ECDH'name 属性仅在类型为 'ECDH' 时可用。

例如:{ type: 'ECDH', name: 'prime256v1', size: 256 }

tlsSocket.getFinished()#

  • 返回:<Buffer> | <undefined> 作为 SSL/TLS 握手的一部分已发送到套接字的最新 Finished 消息,如果尚未发送 Finished 消息,则返回 undefined

由于 Finished 消息是完整握手的消息摘要(对于 TLS 1.0 总共 192 位,对于 SSL 3.0 则更多),当 SSL/TLS 提供的身份验证不需要或不足够时,它们可用于外部身份验证过程。

对应于 OpenSSL 中的 SSL_get_finished 例程,可用于实现 RFC 5929 中的 tls-unique 通道绑定。

tlsSocket.getPeerCertificate([detailed])#

  • detailed <boolean> 如果为 true,则包含完整的证书链,否则仅包含对等方的证书。
  • 返回:<Object> 证书对象。

返回表示对等方证书的对象。如果对等方不提供证书,则返回一个空对象。如果套接字已被销毁,将返回 null

如果请求了完整的证书链,则每个证书将包含一个 issuerCertificate 属性,其中包含表示其颁发者证书的对象。

证书对象#

证书对象具有对应于证书字段的属性。

  • ca <boolean> 如果是证书颁发机构 (CA),则为 true,否则为 false
  • raw <Buffer> DER 编码的 X.509 证书数据。
  • subject <Object> 证书主体,以国家 (C)、州或省 (ST)、地区 (L)、组织 (O)、组织单位 (OU) 和常用名 (CN) 描述。常用名通常是 TLS 证书的 DNS 名称。示例:{C: 'UK', ST: 'BC', L: 'Metro', O: 'Node Fans', OU: 'Docs', CN: 'example.com'}
  • issuer <Object> 证书颁发者,以与 subject 相同的术语描述。
  • valid_from <string> 证书生效的日期时间。
  • valid_to <string> 证书过期的日期时间。
  • serialNumber <string> 证书序列号,作为十六进制字符串。示例:'B9B0D332A1AA5635'
  • fingerprint <string> DER 编码证书的 SHA-1 摘要。它作为 : 分隔的十六进制字符串返回。示例:'2A:7A:C2:DD:...'
  • fingerprint256 <string> DER 编码证书的 SHA-256 摘要。它作为 : 分隔的十六进制字符串返回。示例:'2A:7A:C2:DD:...'
  • fingerprint512 <string> DER 编码证书的 SHA-512 摘要。它作为 : 分隔的十六进制字符串返回。示例:'2A:7A:C2:DD:...'
  • ext_key_usage <Array> (可选)扩展密钥用法,一组 OID。
  • subjectaltname <string> (可选)包含主体连接名称的字符串,主体名称的替代方案。
  • infoAccess <Array> (可选)描述 AuthorityInfoAccess 的数组,与 OCSP 一起使用。
  • issuerCertificate <Object> (可选)颁发者证书对象。对于自签名证书,这可能是一个循环引用。

根据密钥类型,证书可能包含有关公钥的信息。

对于 RSA 密钥,可以定义以下属性:

  • bits <number> RSA 位大小。示例:1024
  • exponent <string> RSA 指数,作为十六进制数字表示法中的字符串。示例:'0x010001'
  • modulus <string> RSA 模数,作为十六进制字符串。示例:'B56CE45CB7...'
  • pubkey <Buffer> 公钥。

对于 EC 密钥,可以定义以下属性:

  • pubkey <Buffer> 公钥。
  • bits <number> 密钥大小(以位为单位)。示例:256
  • asn1Curve <string> (可选)椭圆曲线 OID 的 ASN.1 名称。众所周知的曲线由 OID 标识。虽然不常见,但曲线可能由其数学属性标识,在这种情况下,它将没有 OID。示例:'prime256v1'
  • nistCurve <string> (可选)椭圆曲线的 NIST 名称(如果它有的话)(并非所有众所周知的曲线都由 NIST 指定了名称)。示例:'P-256'

证书示例:

{ subject:
   { OU: [ 'Domain Control Validated', 'PositiveSSL Wildcard' ],
     CN: '*.nodejs.org' },
  issuer:
   { C: 'GB',
     ST: 'Greater Manchester',
     L: 'Salford',
     O: 'COMODO CA Limited',
     CN: 'COMODO RSA Domain Validation Secure Server CA' },
  subjectaltname: 'DNS:*.nodejs.org, DNS:nodejs.org',
  infoAccess:
   { 'CA Issuers - URI':
      [ 'http://crt.comodoca.com/COMODORSADomainValidationSecureServerCA.crt' ],
     'OCSP - URI': [ 'http://ocsp.comodoca.com' ] },
  modulus: 'B56CE45CB740B09A13F64AC543B712FF9EE8E4C284B542A1708A27E82A8D151CA178153E12E6DDA15BF70FFD96CB8A88618641BDFCCA03527E665B70D779C8A349A6F88FD4EF6557180BD4C98192872BCFE3AF56E863C09DDD8BC1EC58DF9D94F914F0369102B2870BECFA1348A0838C9C49BD1C20124B442477572347047506B1FCD658A80D0C44BCC16BC5C5496CFE6E4A8428EF654CD3D8972BF6E5BFAD59C93006830B5EB1056BBB38B53D1464FA6E02BFDF2FF66CD949486F0775EC43034EC2602AEFBF1703AD221DAA2A88353C3B6A688EFE8387811F645CEED7B3FE46E1F8B9F59FAD028F349B9BC14211D5830994D055EEA3D547911E07A0ADDEB8A82B9188E58720D95CD478EEC9AF1F17BE8141BE80906F1A339445A7EB5B285F68039B0F294598A7D1C0005FC22B5271B0752F58CCDEF8C8FD856FB7AE21C80B8A2CE983AE94046E53EDE4CB89F42502D31B5360771C01C80155918637490550E3F555E2EE75CC8C636DDE3633CFEDD62E91BF0F7688273694EEEBA20C2FC9F14A2A435517BC1D7373922463409AB603295CEB0BB53787A334C9CA3CA8B30005C5A62FC0715083462E00719A8FA3ED0A9828C3871360A73F8B04A4FC1E71302844E9BB9940B77E745C9D91F226D71AFCAD4B113AAF68D92B24DDB4A2136B55A1CD1ADF39605B63CB639038ED0F4C987689866743A68769CC55847E4A06D6E2E3F1',
  exponent: '0x10001',
  pubkey: <Buffer ... >,
  valid_from: 'Aug 14 00:00:00 2017 GMT',
  valid_to: 'Nov 20 23:59:59 2019 GMT',
  fingerprint: '01:02:59:D9:C3:D2:0D:08:F7:82:4E:44:A4:B4:53:C5:E2:3A:87:4D',
  fingerprint256: '69:AE:1A:6A:D4:3D:C6:C1:1B:EA:C6:23:DE:BA:2A:14:62:62:93:5C:7A:EA:06:41:9B:0B:BC:87:CE:48:4E:02',
  fingerprint512: '19:2B:3E:C3:B3:5B:32:E8:AE:BB:78:97:27:E4:BA:6C:39:C9:92:79:4F:31:46:39:E2:70:E5:5F:89:42:17:C9:E8:64:CA:FF:BB:72:56:73:6E:28:8A:92:7E:A3:2A:15:8B:C2:E0:45:CA:C3:BC:EA:40:52:EC:CA:A2:68:CB:32',
  ext_key_usage: [ '1.3.6.1.5.5.7.3.1', '1.3.6.1.5.5.7.3.2' ],
  serialNumber: '66593D57F20CBC573E433381B5FEC280',
  raw: <Buffer ... > }

tlsSocket.getPeerFinished()#

  • 返回:<Buffer> | <undefined> 作为 SSL/TLS 握手的一部分,从套接字期望或实际接收到的最新 Finished 消息,如果到目前为止没有 Finished 消息,则返回 undefined

由于 Finished 消息是完整握手的消息摘要(对于 TLS 1.0 总共 192 位,对于 SSL 3.0 则更多),当 SSL/TLS 提供的身份验证不需要或不足够时,它们可用于外部身份验证过程。

对应于 OpenSSL 中的 SSL_get_peer_finished 例程,可用于实现 RFC 5929 中的 tls-unique 通道绑定。

tlsSocket.getPeerX509Certificate()#

将对等方证书作为 <X509Certificate> 对象返回。

如果没有对等方证书,或者套接字已被销毁,将返回 undefined

tlsSocket.getProtocol()#

返回一个包含当前连接协商的 SSL/TLS 协议版本的字符串。对于尚未完成握手过程的已连接套接字,将返回 'unknown'。对于服务器套接字或断开连接的客户端套接字,将返回 null

协议版本为:

  • 'SSLv3'
  • 'TLSv1'
  • 'TLSv1.1'
  • 'TLSv1.2'
  • 'TLSv1.3'

有关更多信息,请参见 OpenSSL SSL_get_version 文档。

tlsSocket.getSession()#

返回 TLS 会话数据,如果未协商会话,则返回 undefined。在客户端,数据可以提供给 tls.connect()session 选项以恢复连接。在服务器上,它可能对调试有用。

更多信息请参见 会话恢复

注意:getSession() 仅适用于 TLSv1.2 及以下版本。对于 TLSv1.3,应用程序必须使用 'session' 事件(它也适用于 TLSv1.2 及以下版本)。

tlsSocket.getSharedSigalgs()#

  • 返回:<Array> 服务器和客户端之间共享的签名算法列表,按优先顺序递减排列。

有关更多信息,请参见 SSL_get_shared_sigalgs

tlsSocket.getTLSTicket()#

对于客户端,返回 TLS 会话票据(如果可用),否则返回 undefined。对于服务器,始终返回 undefined

它可能对调试有用。

更多信息请参见 会话恢复

tlsSocket.getX509Certificate()#

将本地证书作为 <X509Certificate> 对象返回。

如果没有本地证书,或者套接字已被销毁,将返回 undefined

tlsSocket.isSessionReused()#

  • 返回:<boolean> 如果会话已重用,则为 true,否则为 false

更多信息请参见 会话恢复

tlsSocket.localAddress#

返回本地 IP 地址的字符串表示形式。

tlsSocket.localPort#

返回本地端口的数字表示形式。

tlsSocket.remoteAddress#

返回远程 IP 地址的字符串表示形式。例如,'74.125.127.100''2001:4860:a005::68'

tlsSocket.remoteFamily#

返回远程 IP 族的字符串表示形式。'IPv4''IPv6'

tlsSocket.remotePort#

返回远程端口的数字表示形式。例如,443

tlsSocket.renegotiate(options, callback)#

  • options <Object>

    • rejectUnauthorized <boolean> 如果不为 false,则根据提供的 CA 列表验证服务器证书。如果验证失败,将触发 'error' 事件;err.code 包含 OpenSSL 错误代码。默认值: true
    • requestCert
  • callback <Function> 如果 renegotiate() 返回 true,则回调将附加到 'secure' 事件一次。如果 renegotiate() 返回 false,则 callback 将在下一个滴答 (tick) 中被调用并报错,除非 tlsSocket 已被销毁,在这种情况下 callback 将根本不会被调用。

  • 返回:<boolean> 如果发起了重协商,则为 true,否则为 false

tlsSocket.renegotiate() 方法会启动 TLS 重新协商过程。完成后,callback 函数将接收一个参数,该参数要么是 Error(如果请求失败),要么是 null

此方法可用于在建立安全连接后请求对端的证书。

作为服务器运行时,如果超过 handshakeTimeout 超时时间,套接字将被销毁并报错。

对于 TLSv1.3,无法启动重新协商,协议本身不支持此操作。

tlsSocket.setKeyCert(context)#

tlsSocket.setKeyCert() 方法用于设置套接字使用的私钥和证书。如果你希望从 TLS 服务器的 ALPNCallback 中选择服务器证书,此方法非常有用。

tlsSocket.setMaxSendFragment(size)#

  • size <number> 最大 TLS 分片大小。最大值为 16384默认值: 16384
  • 返回:<boolean>

tlsSocket.setMaxSendFragment() 方法设置最大 TLS 分片大小。如果设置限制成功,则返回 true;否则返回 false

较小的分片大小可以减少客户端的缓冲延迟:较大的分片会被 TLS 层缓冲,直到整个分片被接收并验证其完整性;较大的分片可能会跨越多个往返时间,并且由于丢包或重新排序,其处理可能会被延迟。但是,较小的分片会增加额外的 TLS 组帧字节和 CPU 开销,这可能会降低服务器的总吞吐量。

tls.checkServerIdentity(hostname, cert)#

验证证书 cert 是否是为 hostname 签发的。

返回 <Error> 对象,失败时会在其中填充 reasonhostcert 信息。成功时返回 <undefined>

此函数旨在结合可传递给 tls.connect()checkServerIdentity 选项一起使用,因此它对证书对象进行操作。对于其他用途,请考虑使用 x509.checkHost()

可以通过提供替代函数作为传递给 tls.connect()options.checkServerIdentity 选项来覆盖此函数。当然,覆盖函数可以调用 tls.checkServerIdentity(),以使用额外的验证来增强所做的检查。

此函数仅在证书通过所有其他检查(例如由受信任的 CA 签发,即 options.ca)时才会被调用。

旧版本的 Node.js 如果存在匹配的 uniformResourceIdentifier 主题备用名称,会错误地接受针对特定 hostname 的证书(参见 CVE-2021-44531)。希望接受 uniformResourceIdentifier 主题备用名称的应用程序可以使用自定义的 options.checkServerIdentity 函数来实现所需行为。

tls.connect(options[, callback])#

  • options <Object>
  • enableTrace:参见 tls.createServer()
  • host <string> 客户端应连接的主机。默认值: 'localhost'
  • port <number> 客户端应连接的端口。
  • path <string> 创建到该路径的 Unix 套接字连接。如果指定此选项,则忽略 hostport
  • socket <stream.Duplex> 在给定的套接字上建立安全连接,而不是创建新套接字。通常,这是 net.Socket 的实例,但允许任何 Duplex 流。如果指定此选项,除证书验证外,pathhostport 将被忽略。通常在传递给 tls.connect() 时套接字已经连接,但它也可以稍后连接。用户负责 socket 的连接/断开/销毁;调用 tls.connect() 不会导致调用 net.connect()
  • allowHalfOpen <boolean> 如果设为 false,则当可读端结束时,套接字将自动结束可写端。如果设置了 socket 选项,此选项无效。详情请参阅 net.SocketallowHalfOpen 选项。默认值: false
  • rejectUnauthorized <boolean> 如果不为 false,则根据提供的 CA 列表验证服务器证书。如果验证失败,将触发 'error' 事件;err.code 包含 OpenSSL 错误代码。默认值: true
  • pskCallback <Function> 用于 TLS-PSK 协商,请参阅预共享密钥
  • ALPNProtocols <string[]> | <Buffer> | <TypedArray> | <DataView> 包含支持的 ALPN 协议的字符串数组,或单个 BufferTypedArrayDataView。Buffers 应具有 [len][name][len][name]... 格式,例如 '\x08http/1.1\x08http/1.0',其中 len 字节是下一个协议名称的长度。传递数组通常容易得多,例如 ['http/1.1', 'http/1.0']。列表中较靠前的协议比后面的具有更高的优先级。
  • servername <string> 用于 SNI(服务器名称指示)TLS 扩展的服务器名称。它是要连接的主机的名称,必须是主机名,而不是 IP 地址。它可以被多宿主服务器用于选择要呈现给客户端的正确证书,请参见 tls.createServer()SNICallback 选项。
  • checkServerIdentity(servername, cert) <Function> 当根据证书检查服务器的主机名(或明确设置时提供的 servername)时,要使用的回调函数(代替内置的 tls.checkServerIdentity() 函数)。如果验证失败,这应该返回一个 <Error>。如果验证了 servernamecert,该方法应返回 undefined
  • session <Buffer> 包含 TLS 会话的 Buffer 实例。
  • requestOCSP <boolean> 如果为 true,则指定 OCSP 状态请求扩展将被添加到客户端问候(client hello)中,并且在建立安全通信之前会在套接字上触发 'OCSPResponse' 事件。
  • minDHSize <number> 接受 TLS 连接的 DH 参数的最小位数。当服务器提供的 DH 参数大小小于 minDHSize 时,TLS 连接将被销毁并抛出错误。默认值: 1024
  • highWaterMark <number> 与可读流 highWaterMark 参数一致。默认值: 16 * 1024
  • timeout: <number> 如果设置且套接字在内部创建,则将在套接字创建后但在连接开始前调用 socket.setTimeout(timeout)
  • secureContext:使用 tls.createSecureContext() 创建的 TLS 上下文对象。如果提供 secureContext,则通过将整个 options 对象传递给 tls.createSecureContext() 来创建一个。
  • onread <Object> 如果缺少 socket 选项,传入的数据会存储在单个 buffer 中,并在数据到达套接字时传递给提供的 callback,否则该选项将被忽略。详情请参阅 net.Socketonread 选项。
  • ...: 如果缺少 secureContext 选项,则使用 tls.createSecureContext() 选项,否则它们将被忽略。
  • ...: 任何尚未列出的 socket.connect() 选项。
  • callback <Function>
  • 返回: <tls.TLSSocket>
  • 如果指定了 callback 函数,它将被添加为 'secureConnect' 事件的监听器。

    tls.connect() 返回一个 tls.TLSSocket 对象。

    https API 不同,tls.connect() 默认不启用 SNI(服务器名称指示)扩展,这可能导致某些服务器返回错误的证书或直接拒绝连接。要启用 SNI,请在 host 之外设置 servername 选项。

    以下示例展示了 tls.createServer() 回显服务器示例的客户端

    // Assumes an echo server that is listening on port 8000.
    import { connect } from 'node:tls';
    import { readFileSync } from 'node:fs';
    import { stdin } from 'node:process';
    
    const options = {
      // Necessary only if the server requires client certificate authentication.
      key: readFileSync('client-key.pem'),
      cert: readFileSync('client-cert.pem'),
    
      // Necessary only if the server uses a self-signed certificate.
      ca: [ readFileSync('server-cert.pem') ],
    
      // Necessary only if the server's cert isn't for "localhost".
      checkServerIdentity: () => { return null; },
    };
    
    const socket = connect(8000, options, () => {
      console.log('client connected',
                  socket.authorized ? 'authorized' : 'unauthorized');
      stdin.pipe(socket);
      stdin.resume();
    });
    socket.setEncoding('utf8');
    socket.on('data', (data) => {
      console.log(data);
    });
    socket.on('end', () => {
      console.log('server ends connection');
    });
    // Assumes an echo server that is listening on port 8000.
    const { connect } = require('node:tls');
    const { readFileSync } = require('node:fs');
    
    const options = {
      // Necessary only if the server requires client certificate authentication.
      key: readFileSync('client-key.pem'),
      cert: readFileSync('client-cert.pem'),
    
      // Necessary only if the server uses a self-signed certificate.
      ca: [ readFileSync('server-cert.pem') ],
    
      // Necessary only if the server's cert isn't for "localhost".
      checkServerIdentity: () => { return null; },
    };
    
    const socket = connect(8000, options, () => {
      console.log('client connected',
                  socket.authorized ? 'authorized' : 'unauthorized');
      process.stdin.pipe(socket);
      process.stdin.resume();
    });
    socket.setEncoding('utf8');
    socket.on('data', (data) => {
      console.log(data);
    });
    socket.on('end', () => {
      console.log('server ends connection');
    });
    

    要为此示例生成证书和密钥,请运行:

    openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
      -keyout client-key.pem -out client-cert.pem
    

    然后,要为此示例生成 server-cert.pem 证书,请运行

    openssl pkcs12 -certpbe AES-256-CBC -export -out server-cert.pem \
      -inkey client-key.pem -in client-cert.pem
    

    tls.connect(path[, options][, callback])#

    tls.connect() 相同,不同之处在于可以将 path 作为参数而不是选项提供。

    如果指定了 path 选项,它将优先于 path 参数。

    tls.connect(port[, host][, options][, callback])#

    tls.connect() 相同,不同之处在于可以将 porthost 作为参数而不是选项提供。

    如果指定了 port 或 host 选项,它将优先于任何 port 或 host 参数。

    tls.createSecureContext([options])#

    • options <Object>
    • allowPartialTrustChain <boolean> 将受信任 CA 证书列表中的中间(非自签名)证书视为受信任的。
    • ca <string> | <string[]> | <Buffer> | <Buffer[]> 可选地覆盖受信任的 CA 证书。如果未指定,默认受信任的 CA 证书与使用 default 类型调用 tls.getCACertificates() 返回的相同。如果指定了此项,默认列表将被 ca 选项中的证书完全替换(而不是连接)。如果用户希望添加额外的证书而不是完全覆盖默认值,则需要手动连接它们。该值可以是字符串或 Buffer,或者是字符串和/或 Buffer 的数组。任何字符串或 Buffer 都可以包含多个拼接在一起的 PEM CA。对于要验证的连接,对端的证书必须能链至服务器信任的 CA。当使用不能链至知名 CA 的证书时,必须明确指定证书的 CA 为受信任的,否则连接将无法验证。如果对端使用的证书与默认 CA 之一不匹配或无法链接到其中之一,请使用 ca 选项提供一个对端证书可以匹配或链接到的 CA 证书。对于自签名证书,证书本身即是 CA,必须提供。对于 PEM 编码的证书,支持的类型有“TRUSTED CERTIFICATE”、“X509 CERTIFICATE”和“CERTIFICATE”。
    • cert <string> | <string[]> | <Buffer> | <Buffer[]> PEM 格式的证书链。每个私钥应提供一个证书链。每个证书链应由提供的私钥 key 的 PEM 格式证书组成,后跟 PEM 格式的中间证书(如果有),顺序排列,不包括根 CA(根 CA 必须预先为对端所知,请参见 ca)。提供多个证书链时,它们不必与 key 中的私钥顺序相同。如果未提供中间证书,对端将无法验证证书,握手将失败。
    • sigalgs <string> 支持的签名算法的冒号分隔列表。该列表可以包含摘要算法(SHA256MD5 等)、公钥算法(RSA-PSSECDSA 等)、两者的组合(例如 'RSA+SHA384')或 TLS v1.3 方案名称(例如 rsa_pss_pss_sha512)。有关更多信息,请参阅 OpenSSL 手册页
    • ciphers <string> 密码套件规范,替换默认值。有关更多信息,请参阅修改默认 TLS 密码套件。可以通过 tls.getCiphers() 获取允许的密码。密码名称必须大写,OpenSSL 才能接受它们。
    • clientCertEngine <string> 可提供客户端证书的 OpenSSL 引擎名称。已弃用。
    • crl <string> | <string[]> | <Buffer> | <Buffer[]> PEM 格式的 CRL(证书吊销列表)。
    • dhparam <string> | <Buffer> 'auto' 或自定义的 Diffie-Hellman 参数,对于非 ECDHE 完美前向保密是必需的。如果省略或无效,参数将被静默丢弃,DHE 密码将不可用。基于 ECDHE完美前向保密仍然可用。
    • ecdhCurve <string> 描述命名曲线的字符串或冒号分隔的曲线 NID 或名称列表,例如 P-521:P-384:P-256,用于 ECDH 密钥协商。设置为 auto 可自动选择曲线。使用 crypto.getCurves() 获取可用曲线名称的列表。在最近的版本中,openssl ecparam -list_curves 也会显示每个可用椭圆曲线的名称和描述。默认值: tls.DEFAULT_ECDH_CURVE
    • honorCipherOrder <boolean> 尝试使用服务器的密码套件偏好而不是客户端的。当为 true 时,会导致 secureOptions 中设置 SSL_OP_CIPHER_SERVER_PREFERENCE,有关更多信息,请参阅 OpenSSL 选项
    • key <string> | <string[]> | <Buffer> | <Buffer[]> | <Object[]> PEM 格式的私钥。PEM 允许选择私钥加密。加密密钥将使用 options.passphrase 解密。可以使用不同算法的多个密钥,形式为未加密密钥字符串或 Buffer 的数组,或者形式为 {pem: <string|buffer>[, passphrase: <string>]} 的对象数组。对象形式只能出现在数组中。object.passphrase 是可选的。如果提供了加密密钥,将使用 object.passphrase(如果提供)解密,或者使用 options.passphrase(如果未提供)。
    • privateKeyEngine <string> 从中获取私钥的 OpenSSL 引擎名称。应与 privateKeyIdentifier 一起使用。已弃用。
    • privateKeyIdentifier <string> OpenSSL 引擎管理的私钥标识符。应与 privateKeyEngine 一起使用。不应与 key 同时设置,因为两个选项以不同方式定义私钥。已弃用。
    • maxVersion <string> 可选地设置允许的最大 TLS 版本。可以是 'TLSv1.3''TLSv1.2''TLSv1.1''TLSv1' 之一。不能与 secureProtocol 选项一起指定;使用其中一个即可。默认值: tls.DEFAULT_MAX_VERSION
    • minVersion <string> 可选地设置允许的最小 TLS 版本。可以是 'TLSv1.3''TLSv1.2''TLSv1.1''TLSv1' 之一。不能与 secureProtocol 选项一起指定;使用其中一个即可。尽量避免将其设置为低于 TLSv1.2,但这可能是互操作性所必需的。TLSv1.2 之前的版本可能需要降低 OpenSSL 安全级别默认值: tls.DEFAULT_MIN_VERSION
    • passphrase <string> 用于单个私钥和/或 PFX 的共享密码。
    • pfx <string> | <string[]> | <Buffer> | <Buffer[]> | <Object[]> PFX 或 PKCS12 编码的私钥和证书链。pfx 是单独提供 keycert 的替代方案。PFX 通常是加密的,如果是,则使用 passphrase 解密。可以提供多个 PFX,形式为未加密 PFX Buffer 的数组,或者形式为 {buf: <string|buffer>[, passphrase: <string>]} 的对象数组。对象形式只能出现在数组中。object.passphrase 是可选的。加密的 PFX 将使用 object.passphrase(如果提供)解密,或者使用 options.passphrase(如果未提供)。
    • secureOptions <number> 可选地影响 OpenSSL 协议行为,通常不需要。如果使用,请务必小心!该值是 OpenSSL 选项SSL_OP_* 选项的数值位掩码。
    • secureProtocol <string> 选择要使用的 TLS 协议版本的遗留机制,它不支持独立控制最小和最大版本,也不支持将协议限制为 TLSv1.3。请改用 minVersionmaxVersion。可能的值列为 SSL_METHODS,将函数名称用作字符串即可。例如,使用 'TLSv1_1_method' 强制使用 TLS 1.1 版本,或者使用 'TLS_method' 允许任何最高达 TLSv1.3 的 TLS 协议版本。不建议使用低于 1.2 的 TLS 版本,但出于互操作性目的可能需要。默认值: 无,请参见 minVersion
    • sessionIdContext <string> 服务器使用的不透明标识符,确保会话状态不会在应用程序之间共享。客户端不使用。
    • ticketKeys <Buffer> 48 字节的加密强伪随机数据。有关更多信息,请参见会话恢复
    • sessionTimeout <number> 服务器创建的 TLS 会话在多少秒后将不再可恢复。有关更多信息,请参见会话恢复默认值: 300

    tls.createServer()honorCipherOrder 选项的默认值设置为 true,其他创建安全上下文的 API 则不设置。

    tls.createServer() 使用从 process.argv 生成的 128 位截断 SHA1 哈希值作为 sessionIdContext 选项的默认值,其他创建安全上下文的 API 没有默认值。

    tls.createSecureContext() 方法创建一个 SecureContext 对象。它可用作几个 tls API 的参数,例如 server.addContext(),但没有公共方法。tls.Server 构造函数和 tls.createServer() 方法不支持 secureContext 选项。

    对于使用证书的密码,密钥是必需的。可以使用 keypfx 来提供。

    如果未给出 ca 选项,则 Node.js 默认使用 Mozilla 公开受信任的 CA 列表

    不鼓励使用自定义 DHE 参数,建议采用新的 dhparam: 'auto' 选项。当设置为 'auto' 时,将自动选择足够强度的知名 DHE 参数。否则,如果有必要,可以使用 openssl dhparam 创建自定义参数。密钥长度必须大于或等于 1024 位,否则将抛出错误。虽然 1024 位是允许的,但请使用 2048 位或更大以获得更强的安全性。

    tls.createServer([options][, secureConnectionListener])#

    • options <Object>
    • ALPNProtocols <string[]> | <Buffer> | <TypedArray> | <DataView> 包含支持的 ALPN 协议的字符串数组,或单个 BufferTypedArrayDataView。Buffers 应具有 [len][name][len][name]... 格式,例如 0x05hello0x05world,其中第一个字节是下一个协议名称的长度。传递数组通常容易得多,例如 ['hello', 'world']。(协议应按优先级排序。)
    • ALPNCallback <Function> 如果设置,当客户端使用 ALPN 扩展打开连接时,将调用此函数。一个参数将传递给回调:一个包含 servernameprotocols 字段的对象,分别包含来自 SNI 扩展的服务器名称(如果有)和 ALPN 协议名称字符串数组。回调必须返回 protocols 中列出的字符串之一(这将作为选定的 ALPN 协议返回给客户端),或者返回 undefined 以致命警报拒绝连接。如果返回的字符串与客户端的任何 ALPN 协议不匹配,将抛出错误。此选项不能与 ALPNProtocols 选项一起使用,同时设置两个选项将抛出错误。
    • clientCertEngine <string> 可提供客户端证书的 OpenSSL 引擎名称。已弃用。
    • enableTrace <boolean> 如果为 true,则将在新连接上调用 tls.TLSSocket.enableTrace()。可以在安全连接建立后启用跟踪,但必须使用此选项来跟踪安全连接的设置。默认值: false
    • handshakeTimeout <number> 如果 SSL/TLS 握手未在指定的毫秒数内完成,则中止连接。每当握手超时时,都会在 tls.Server 对象上触发 'tlsClientError'默认值: 120000(120 秒)。
    • rejectUnauthorized <boolean> 如果不为 false,则服务器将拒绝任何未被提供的 CA 列表授权的连接。此选项仅在 requestCerttrue 时才有效。默认值: true
    • requestCert <boolean> 如果为 true,服务器将请求连接的客户端提供证书,并尝试验证该证书。默认值: false
    • sessionTimeout <number> 服务器创建的 TLS 会话在多少秒后将不再可恢复。有关更多信息,请参见会话恢复默认值: 300
    • SNICallback(servername, callback) <Function> 如果客户端支持 SNI TLS 扩展,将调用的函数。调用时将传递两个参数:servernamecallbackcallback 是一个错误优先的回调,接受两个可选参数:errorctx。如果提供,ctx 是一个 SecureContext 实例。tls.createSecureContext() 可用于获取合适的 SecureContext。如果使用虚假的 ctx 参数调用 callback,则将使用服务器的默认安全上下文。如果未提供 SNICallback,将使用具有高级 API 的默认回调(见下文)。
    • ticketKeys <Buffer> 48 字节的加密强伪随机数据。有关更多信息,请参见会话恢复
    • pskCallback <Function> 用于 TLS-PSK 协商,请参阅预共享密钥
    • pskIdentityHint <string> 可选提示,发送给客户端以帮助在 TLS-PSK 协商期间选择身份。在 TLS 1.3 中将被忽略。设置 pskIdentityHint 失败时,将触发带有 'ERR_TLS_PSK_SET_IDENTITY_HINT_FAILED' 代码的 'tlsClientError' 事件。
    • ...: 可以提供任何 tls.createSecureContext() 选项。对于服务器,身份选项(pfxkey/certpskCallback)通常是必需的。
    • ...: 可以提供任何 net.createServer() 选项。
  • secureConnectionListener <Function>
  • 返回:<tls.Server>
  • 创建一个新的 tls.Server。如果提供了 secureConnectionListener,它会自动设置为 'secureConnection' 事件的监听器。

    ticketKeys 选项会在 node:cluster 模块工作进程之间自动共享。

    以下示例展示了一个简单的回显服务器

    import { createServer } from 'node:tls';
    import { readFileSync } from 'node:fs';
    
    const options = {
      key: readFileSync('server-key.pem'),
      cert: readFileSync('server-cert.pem'),
    
      // This is necessary only if using client certificate authentication.
      requestCert: true,
    
      // This is necessary only if the client uses a self-signed certificate.
      ca: [ readFileSync('client-cert.pem') ],
    };
    
    const server = createServer(options, (socket) => {
      console.log('server connected',
                  socket.authorized ? 'authorized' : 'unauthorized');
      socket.write('welcome!\n');
      socket.setEncoding('utf8');
      socket.pipe(socket);
    });
    server.listen(8000, () => {
      console.log('server bound');
    });
    const { createServer } = require('node:tls');
    const { readFileSync } = require('node:fs');
    
    const options = {
      key: readFileSync('server-key.pem'),
      cert: readFileSync('server-cert.pem'),
    
      // This is necessary only if using client certificate authentication.
      requestCert: true,
    
      // This is necessary only if the client uses a self-signed certificate.
      ca: [ readFileSync('client-cert.pem') ],
    };
    
    const server = createServer(options, (socket) => {
      console.log('server connected',
                  socket.authorized ? 'authorized' : 'unauthorized');
      socket.write('welcome!\n');
      socket.setEncoding('utf8');
      socket.pipe(socket);
    });
    server.listen(8000, () => {
      console.log('server bound');
    });
    

    要为此示例生成证书和密钥,请运行:

    openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
      -keyout server-key.pem -out server-cert.pem
    

    然后,要为此示例生成 client-cert.pem 证书,请运行

    openssl pkcs12 -certpbe AES-256-CBC -export -out client-cert.pem \
      -inkey server-key.pem -in server-cert.pem
    

    可以通过使用 tls.connect() 中的示例客户端连接到服务器来测试服务器。

    tls.setDefaultCACertificates(certs)#

    设置 Node.js TLS 客户端使用的默认 CA 证书。如果成功解析提供的证书,它们将成为 tls.getCACertificates() 返回的默认 CA 证书列表,并供后续未指定自己 CA 证书的 TLS 连接使用。在设置为默认值之前,证书将被去重。

    此函数仅影响当前的 Node.js 线程。HTTPS 代理缓存的先前会话不会受到此更改的影响,因此应在进行任何不需要的可缓存 TLS 连接之前调用此方法。

    要使用系统 CA 证书作为默认值

    const tls = require('node:tls');
    tls.setDefaultCACertificates(tls.getCACertificates('system'));
    import tls from 'node:tls';
    tls.setDefaultCACertificates(tls.getCACertificates('system'));
    

    此函数完全替换默认的 CA 证书列表。要将额外的证书添加到现有默认值,请获取当前证书并附加到它们后面

    const tls = require('node:tls');
    const currentCerts = tls.getCACertificates('default');
    const additionalCerts = ['-----BEGIN CERTIFICATE-----\n...'];
    tls.setDefaultCACertificates([...currentCerts, ...additionalCerts]);
    import tls from 'node:tls';
    const currentCerts = tls.getCACertificates('default');
    const additionalCerts = ['-----BEGIN CERTIFICATE-----\n...'];
    tls.setDefaultCACertificates([...currentCerts, ...additionalCerts]);
    

    tls.getCACertificates([type])#

    • type <string> | <undefined> 将返回的 CA 证书类型。有效值为 "default""system""bundled""extra"默认值: "default"
    • 返回: <string[]> PEM 编码的证书数组。如果相同的证书重复存储在多个来源中,则数组可能包含重复项。

    返回一个包含来自各种来源的 CA 证书的数组,具体取决于 type

    • "default":返回 Node.js TLS 客户端默认使用的 CA 证书。
    • "system":返回根据 --use-system-ca 设置的规则从系统受信任存储加载的 CA 证书。这可用于在未启用 --use-system-ca 时从系统中获取证书。
    • "bundled":返回来自捆绑的 Mozilla CA 存储的 CA 证书。这与 tls.rootCertificates 相同。
    • "extra":返回从 NODE_EXTRA_CA_CERTS 加载的 CA 证书。如果未设置 NODE_EXTRA_CA_CERTS,它是一个空数组。

    tls.getCiphers()#

    返回一个包含受支持 TLS 密码名称的数组。由于历史原因,名称是小写的,但必须大写才能在 tls.createSecureContext()ciphers 选项中使用。

    并非所有支持的密码默认都是启用的。请参见修改默认 TLS 密码套件

    'tls_' 开头的密码名称用于 TLSv1.3,所有其他名称用于 TLSv1.2 及以下版本。

    console.log(tls.getCiphers()); // ['aes128-gcm-sha256', 'aes128-sha', ...]
    

    tls.rootCertificates#

    一个不可变的字符串数组,代表当前 Node.js 版本提供的来自捆绑的 Mozilla CA 存储的根证书(PEM 格式)。

    Node.js 提供的捆绑 CA 存储是发布时固定的 Mozilla CA 存储快照。它在所有支持的平台上都是相同的。

    要获取当前 Node.js 实例使用的实际 CA 证书(可能包括从系统存储加载的证书(如果使用了 --use-system-ca)或从 NODE_EXTRA_CA_CERTS 指示的文件加载的证书),请使用 tls.getCACertificates()

    tls.DEFAULT_ECDH_CURVE#

    用于 TLS 服务器中 ECDH 密钥协商的默认曲线名称。默认值为 'auto'。有关更多信息,请参见 tls.createSecureContext()

    tls.DEFAULT_MAX_VERSION#

    • 类型: <string> tls.createSecureContext()maxVersion 选项的默认值。它可以分配任何受支持的 TLS 协议版本:'TLSv1.3''TLSv1.2''TLSv1.1''TLSv1'默认值: 'TLSv1.3',除非使用 CLI 选项更改。使用 --tls-max-v1.2 将默认值设置为 'TLSv1.2'。使用 --tls-max-v1.3 将默认值设置为 'TLSv1.3'。如果提供了多个选项,则使用最高的最大值。

    tls.DEFAULT_MIN_VERSION#

    • 类型: <string> tls.createSecureContext()minVersion 选项的默认值。它可以分配任何受支持的 TLS 协议版本:'TLSv1.3''TLSv1.2''TLSv1.1''TLSv1'。TLSv1.2 之前的版本可能需要降低 OpenSSL 安全级别默认值: 'TLSv1.2',除非使用 CLI 选项更改。使用 --tls-min-v1.0 将默认值设置为 'TLSv1'。使用 --tls-min-v1.1 将默认值设置为 'TLSv1.1'。使用 --tls-min-v1.3 将默认值设置为 'TLSv1.3'。如果提供了多个选项,则使用最低的最小值。

    tls.DEFAULT_CIPHERS#

    • 类型: <string> tls.createSecureContext()ciphers 选项的默认值。它可以分配任何受支持的 OpenSSL 密码。默认为 crypto.constants.defaultCoreCipherList 的内容,除非使用 --tls-default-ciphers 的 CLI 选项更改。