Ela*_*ava 11 javascript ssl openssl node.js tls1.2
Node.js TLS_EMPTY_RENEGOTIATION_INFO_SCSV默认发送密码以保护自己免受POODLE攻击.
我试图通过使用自定义密码列表覆盖TLS密码来避免发送此密码(即使这可能会带来安全风险).
但是,TLS_EMPTY_RENEGOTIATION_INFO_SCSV无论我做什么,Node.js都会继续发送密码.我试图故意避免发送此密码来模仿Firefox/Chrome的TLS协商.
这是我用来修改和检查节点发送的密码的代码:
var request = require('request');
var ciphers = [
'ECDHE-ECDSA-AES128-GCM-SHA256',
'ECDHE-RSA-AES128-GCM-SHA256',
'ECDHE-ECDSA-AES256-SHA',
'ECDHE-ECDSA-AES128-SHA',
'ECDHE-RSA-AES128-SHA',
'ECDHE-RSA-AES256-SHA',
'DHE-RSA-AES128-SHA',
'DHE-RSA-AES256-SHA',
'AES128-SHA',
'AES256-SHA',
'DES-CBC3-SHA'
].join(':');
var options = {
ciphers: ciphers,
secureProtocol: 'TLSv1_2_method',
url: 'https://www.howsmyssl.com/a/check'
};
request(options, function (error, response, body){
if (!error) {
console.log(body);
}
else {
console.log(error);
}
});
Run Code Online (Sandbox Code Playgroud)
有没有办法禁止在Node.js中发送此密码?
鉴于此问题与 Node.js 有关,有一种简单的方法可以处理您的问题,而无需实际深入研究:
在 Node.js 进程前面放置一个 Web 代理,并让它处理完整的 SSL 连接。在 Node.js 代码本身中,您只需向本地 HTTP 服务器发送请求。
nginx 配置示例(在 http 指令内):
server {
listen 8080;
location / {
resolver 8.8.8.8;
proxy_pass https://www.howsmyssl.com$uri$is_args&args;
proxy_ssl_protocols TLSv1.2;
proxy_ssl_ciphers AESGCM:!aNULL;
}
}
Run Code Online (Sandbox Code Playgroud)
并将nodejs更改为:
var request = require('request');
var options = {
url: 'http://localhost:8080/a/check'
};
request(options, function (error, response, body){
if (!error) {
console.log(body);
}
else {
console.log(error);
}
});
Run Code Online (Sandbox Code Playgroud)
不幸的是,虽然我实际上这样做了,但结果是一样的:
{"given_cipher_suites":["TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384","TLS_DH_DSS_WITH_AES_256_GCM_SHA384","TLS_DHE_DSS_WITH_AES_256_GCM_SHA384","TLS_DH_RSA_WITH_AES_256_GCM_SHA384","TLS_DHE_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384","TLS_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256","TLS_DH_DSS_WITH_AES_128_GCM_SHA256","TLS_DHE_DSS_WITH_AES_128_GCM_SHA256","TLS_DH_RSA_WITH_AES_128_GCM_SHA256","TLS_DHE_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256","TLS_RSA_WITH_AES_128_GCM_SHA256","TLS_EMPTY_RENEGOTIATION_INFO_SCSV"],"ephemeral_keys_supported":true,"session_ticket_supported":true,"tls_compression_supported":false,"unknown_cipher_suite_supported":false,"beast_vuln":false,"able_to_detect_n_minus_one_splitting":false,"insecure_cipher_suites":{},"tls_version":"TLS 1.2","rating":"Probably Okay"}
Run Code Online (Sandbox Code Playgroud)
这基本上意味着它可能是标准的 OpenSSL 行为。
可以使用SSL_CTX_set_options在 OpenSSL 中设置一些选项
这里特别有趣的是“安全重新协商”部分和这个选项:
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
允许 OpenSSL 与未打补丁的客户端或服务器之间进行传统的不安全重新协商。有关更多详细信息,请参阅“安全重新协商”部分。
但我不确定这是否真的阻止了重新协商密码的发送。如果此选项实际上是正确的,则可能有一种方法可以修补 Node.js 以使用该选项或使用该选项重新编译 OpenSSL。
当然,也可以选择使用旧的未修补版本。据我了解,虽然TLS_EMPTY_RENEGOTIATION_INFO_SCSV与 POODLE 无关,但来自较旧的修复:
CVE-2009-3555(OpenSSL 公告)2009 年 11 月 5 日:
实施 RFC5746 以解决 SSL/TLS 重新协商中的漏洞。在 OpenSSL 0.9.8m 中已修复(受影响的 0.9.8l、0.9.8k、0.9.8j、0.9.8i、0.9.8h、0.9.8g、0.9.8f、0.9.8e、0.9.8d、0.9.8c、0.9。 8b、0.9.8a、0.9.8)
现代 Node.js 附带了静态链接的 OpenSSL,但不支持 OpenSSL 0.9.8,因此无论如何,您都需要旧版本的 Node.js...或者将 nginx 内容与未修补的 OpenSSL 一起使用...
这就是我被困住的地方。这并不是一个完整的答案,但我认为至少值得分享。
总而言之,我认为如果您想在不重新编译的情况下执行此操作,请使用带有未修补的 OpenSSL 的 nginx,并配置多个服务器,每个服务器对应一个您想要模拟的客户端。
如果您需要在节点中单独完成此操作,那么最好的选择是直接修补 OpenSSL 并重新编译节点。
| 归档时间: |
|
| 查看次数: |
2684 次 |
| 最近记录: |