为啥 Node.js TLS 支持的密码不对应于 openssl 支持的密码?

Posted

技术标签:

【中文标题】为啥 Node.js TLS 支持的密码不对应于 openssl 支持的密码?【英文标题】:Why don't Node.js TLS supported ciphers correspond to the openssl supported ciphers?为什么 Node.js TLS 支持的密码不对应于 openssl 支持的密码? 【发布时间】:2014-02-10 16:54:36 【问题描述】:

根据openssl,这些是它支持的密码:

 DHE-RSA-AES256-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA1
 DHE-DSS-AES256-SHA      SSLv3 Kx=DH       Au=DSS  Enc=AES(256)  Mac=SHA1
 AES256-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(256)  Mac=SHA1
 EDH-RSA-DES-CBC3-SHA    SSLv3 Kx=DH       Au=RSA  Enc=3DES(168) Mac=SHA1
 EDH-DSS-DES-CBC3-SHA    SSLv3 Kx=DH       Au=DSS  Enc=3DES(168) Mac=SHA1
 DES-CBC3-SHA            SSLv3 Kx=RSA      Au=RSA  Enc=3DES(168) Mac=SHA1
 DES-CBC3-MD5            SSLv2 Kx=RSA      Au=RSA  Enc=3DES(168) Mac=MD5 
 DHE-RSA-AES128-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(128)  Mac=SHA1
 DHE-DSS-AES128-SHA      SSLv3 Kx=DH       Au=DSS  Enc=AES(128)  Mac=SHA1
 AES128-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(128)  Mac=SHA1
 RC2-CBC-MD5             SSLv2 Kx=RSA      Au=RSA  Enc=RC2(128)  Mac=MD5 
 RC4-SHA                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=SHA1
 RC4-MD5                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=MD5 
 RC4-MD5                 SSLv2 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=MD5 
 EDH-RSA-DES-CBC-SHA     SSLv3 Kx=DH       Au=RSA  Enc=DES(56)   Mac=SHA1
 EDH-DSS-DES-CBC-SHA     SSLv3 Kx=DH       Au=DSS  Enc=DES(56)   Mac=SHA1
 DES-CBC-SHA             SSLv3 Kx=RSA      Au=RSA  Enc=DES(56)   Mac=SHA1
 DES-CBC-MD5             SSLv2 Kx=RSA      Au=RSA  Enc=DES(56)   Mac=MD5 
 EXP-EDH-RSA-DES-CBC-SHA SSLv3 Kx=DH(512)  Au=RSA  Enc=DES(40)   Mac=SHA1 export
 EXP-EDH-DSS-DES-CBC-SHA SSLv3 Kx=DH(512)  Au=DSS  Enc=DES(40)   Mac=SHA1 export
 EXP-DES-CBC-SHA         SSLv3 Kx=RSA(512) Au=RSA  Enc=DES(40)   Mac=SHA1 export
 EXP-RC2-CBC-MD5         SSLv3 Kx=RSA(512) Au=RSA  Enc=RC2(40)   Mac=MD5  export
 EXP-RC2-CBC-MD5         SSLv2 Kx=RSA(512) Au=RSA  Enc=RC2(40)   Mac=MD5  export
 EXP-RC4-MD5             SSLv3 Kx=RSA(512) Au=RSA  Enc=RC4(40)   Mac=MD5  export
 EXP-RC4-MD5             SSLv2 Kx=RSA(512) Au=RSA  Enc=RC4(40)   Mac=MD5  export

我在端口 443 上运行一个简单的 node.js https 服务器。当我运行 sslscan 时,以下是 Accepted 密码:

 Accepted  SSLv3  256 bits  AES256-SHA
 Accepted  SSLv3  128 bits  AES128-SHA
 Accepted  SSLv3  168 bits  DES-CBC3-SHA
 Accepted  SSLv3  128 bits  RC4-SHA
 Accepted  TLSv1  256 bits  AES256-SHA
 Accepted  TLSv1  128 bits  AES128-SHA
 Accepted  TLSv1  168 bits  DES-CBC3-SHA
 Accepted  TLSv1  128 bits  RC4-SHA

我不明白的是,为什么实际支持的密码列表这么短?

更令人困惑的是,当我在节点中获得支持的密码列表tls.getCiphers() 时,我发现了一个很长的列表:

['aes128-gcm-sha256', 'aes128-sha', 'aes128-sha256', 'aes256-gcm-sha384', 'aes256-sha', 'aes256-sha256', 'camellia128-sha', 'camellia256-sha', 'des-cbc-sha', 'des-cbc3-sha', 'dhe-dss-aes128-gcm-sha256', 'dhe-dss-aes128-sha', 'dhe-dss-aes128-sha256', 'dhe-dss-aes256-gcm-sha384', 'dhe-dss-aes256-sha', 'dhe-dss-aes256-sha256', 'dhe-dss-camellia128-sha', 'dhe-dss-camellia256-sha', 'dhe-dss-seed-sha', 'dhe-rsa-aes128-gcm-sha256', 'dhe-rsa-aes128-sha', 'dhe-rsa-aes128-sha256', 'dhe-rsa-aes256-gcm-sha384', 'dhe-rsa-aes256-sha', 'dhe-rsa-aes256-sha256', 'dhe-rsa-camellia128-sha', 'dhe-rsa-camellia256-sha', 'dhe-rsa-seed-sha', 'ecdh-ecdsa-aes128-gcm-sha256', 'ecdh-ecdsa-aes128-sha', 'ecdh-ecdsa-aes128-sha256', 'ecdh-ecdsa-aes256-gcm-sha384', 'ecdh-ecdsa-aes256-sha', 'ecdh-ecdsa-aes256-sha384', 'ecdh-ecdsa-des-cbc3-sha', 'ecdh-ecdsa-rc4-sha', 'ecdh-rsa-aes128-gcm-sha256', 'ecdh-rsa-aes128-sha', 'ecdh-rsa-aes128-sha256', 'ecdh-rsa-aes256-gcm-sha384', 'ecdh-rsa-aes256-sha', 'ecdh-rsa-aes256-sha384', 'ecdh-rsa-des-cbc3-sha', 'ecdh-rsa-rc4-sha', 'ecdhe-ecdsa-aes128-gcm-sha256', 'ecdhe-ecdsa-aes128-sha', 'ecdhe-ecdsa-aes128-sha256', 'ecdhe-ecdsa-aes256-gcm-sha384', 'ecdhe-ecdsa-aes256-sha', 'ecdhe-ecdsa-aes256-sha384', 'ecdhe-ecdsa-des-cbc3-sha', 'ecdhe-ecdsa-rc4-sha', 'ecdhe-rsa-aes128-gcm-sha256', 'ecdhe-rsa-aes128-sha', 'ecdhe-rsa-aes128-sha256', 'ecdhe-rsa-aes256-gcm-sha384', 'ecdhe-rsa-aes256-sha', 'ecdhe-rsa-aes256-sha384', 'ecdhe-rsa-des-cbc3-sha', 'ecdhe-rsa-rc4-sha', 'edh-dss-des-cbc-sha', 'edh-dss-des-cbc3-sha', 'edh-rsa-des-cbc-sha', 'edh-rsa-des-cbc3-sha', 'exp-des-cbc-sha', 'exp-edh-dss-des-cbc-sha', 'exp-edh-rsa-des-cbc-sha', 'exp-rc2-cbc-md5', 'exp-rc4-md5', 'idea-cbc-sha', 'psk-3des-ede-cbc-sha', 'psk-aes128-cbc-sha', 'psk-aes256-cbc-sha', 'psk-rc4-sha', 'rc4-md5', 'rc4-sha', '种子沙', 'srp-dss-3des-ede-cbc-sha', 'srp-dss-aes-128-cbc-sha', 'srp-dss-aes-256-cbc-sha', 'srp-rsa-3des-ede-cbc-sha', 'srp-rsa-aes-128-cbc-sha', 'srp-rsa-aes-256-cbc-sha']

【问题讨论】:

sslscan 仅测试 SSLv2、SSLv3 和 TLS 1.0。因此,您将丢失所有 TLS 1.2 密码套件,例如 GCM 套件(TLS 1.1 未添加任何密码套件)。可用列表将进一步修剪为SSL_CTX_set_cipher_list("HIGH:!ADH"); 【参考方案1】:

第一个列表是 SSLv3 的所有密码。目前已经定义了 TLS 1.0、TLS 1.1 和 TLS.2。所以这些是较旧的密码。

第二个列表是握手时客户端(sslscan)和服务器都可用的密码列表。

最后,最后一个似乎是 NodeJS 中存在(但可能未配置?)的完整密码列表。

请注意,众所周知,OpenSSL 文档很少而且经常过时,而 NodeJS 的表现稍好一些。

【讨论】:

谢谢。我不明白的是,当 sslscan 尝试连接此密码套件时,为什么会拒绝“SSLv3 DHE-RSA-AES256-SHA”之类的东西?我的意思是它建立在 OpenSSL 之上,就像 node.js 一样。 我认为这主要是由于当前配置和可能匹配密钥的可用性(例如,对于 DHE,您需要一个适合签名的密钥)。我不确定 OpenSSL 在这方面有多聪明。 晚了,但 nodejs/OpenSSL 上的 DHE 需要签名证书 dhparam 值;见nodejs.org/docs/latest-v14.x/api/…; ECDHE 只需要一个签名证书,这让我更惊讶于它的遗漏。【参考方案2】:

Node 默认禁用许多旧的、不安全的密码。您可以在node documentation 中看到默认启用的密码(请注意,这可能会因您使用的节点版本而异)。

正如 jww 所指出的,sslscan 的旧版本(您似乎正在使用)不支持 TLSv1.1/1.2,因此不会检测到一些较新的密码(如 GCM 套件)。 updated version 可以。

【讨论】:

以上是关于为啥 Node.js TLS 支持的密码不对应于 openssl 支持的密码?的主要内容,如果未能解决你的问题,请参考以下文章

在 Node JS TLS 中添加/启用从 SSLv3 (DHE-RSA-AES256-SHA) 到 TLS 1.2 的密码

nestjs为啥不火

TLS是否支持IOS / IEC 29192标准定义的轻量级加密?

NGINX 不支持 tls1.2 密码

为啥 IndexedDB 在 node.js 中不可用? [关闭]

在Node.js SOAP客户端中设置授权