修改默认的 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

也可以使用 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.2 TLSv1.3 密码套件已启用。

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

默认密码套件更喜欢 Chrome 的‘现代密码学’设置的 GCM 密码,并且还更喜欢 ECDHE 和 DHE 密码以实现完美的前向保密,同时提供一些向后兼容性。

鉴于影响更大 AES 密钥大小的特定攻击,128 位 AES 优于 192 位和 256 位 AES。

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

只有 5 个 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'

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

Node.js is built with a default suite of enabled and disabled TLS ciphers. This default cipher list can be configured when building Node.js to allow distributions to provide their own default list.

The following command can be used to show the default cipher suite:

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

This default can be replaced entirely using the --tls-cipher-list command-line switch (directly, or via the NODE_OPTIONS environment variable). For instance, the following makes ECDHE-RSA-AES128-GCM-SHA256:!RC4 the default TLS cipher suite:

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

The default can also be replaced on a per client or server basis using the ciphers option from tls.createSecureContext(), which is also available in tls.createServer(), tls.connect(), and when creating new tls.TLSSockets.

The ciphers list can contain a mixture of TLSv1.3 cipher suite names, the ones that start with 'TLS_', and specifications for TLSv1.2 and below cipher suites. The TLSv1.2 ciphers support a legacy specification format, consult the OpenSSL cipher list format documentation for details, but those specifications do not apply to TLSv1.3 ciphers. The TLSv1.3 suites can only be enabled by including their full name in the cipher list. They cannot, for example, be enabled or disabled by using the legacy TLSv1.2 'EECDH' or '!EECDH' specification.

Despite the relative order of TLSv1.3 and TLSv1.2 cipher suites, the TLSv1.3 protocol is significantly more secure than TLSv1.2, and will always be chosen over TLSv1.2 if the handshake indicates it is supported, and if any TLSv1.3 cipher suites are enabled.

The default cipher suite included within Node.js has been carefully selected to reflect current security best practices and risk mitigation. Changing the default cipher suite can have a significant impact on the security of an application. The --tls-cipher-list switch and ciphers option should by used only if absolutely necessary.

The default cipher suite prefers GCM ciphers for Chrome's 'modern cryptography' setting and also prefers ECDHE and DHE ciphers for perfect forward secrecy, while offering some backward compatibility.

128 bit AES is preferred over 192 and 256 bit AES in light of specific attacks affecting larger AES key sizes.

Old clients that rely on insecure and deprecated RC4 or DES-based ciphers (like Internet Explorer 6) cannot complete the handshaking process with the default configuration. If these clients must be supported, the TLS recommendations may offer a compatible cipher suite. For more details on the format, see the OpenSSL cipher list format documentation.

There are only 5 TLSv1.3 cipher suites:

  • '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'

The first 3 are enabled by default. The last 2 CCM-based suites are supported by TLSv1.3 because they may be more performant on constrained systems, but they are not enabled by default since they offer less security.