避免在 TLS Client Hello 中发送 TLS_EMPTY_RENEGOTIATION_INFO_SCSV 密码 [英] Avoid sending TLS_EMPTY_RENEGOTIATION_INFO_SCSV cipher in TLS Client Hello

查看:411
本文介绍了避免在 TLS Client Hello 中发送 TLS_EMPTY_RENEGOTIATION_INFO_SCSV 密码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Node.js 默认发送 TLS_EMPTY_RENEGOTIATION_INFO_SCSV 密码以保护自己免受POODLE 攻击.

Node.js sends the TLS_EMPTY_RENEGOTIATION_INFO_SCSV cipher by default to protect itself against the POODLE attack.

我试图通过使用自定义密码列表覆盖 TLS 密码来避免发送此密码(即使这可能会带来安全风险).

I'm trying to avoid sending this cipher (even though this may pose a security risk) by overriding the TLS ciphers with a custom list of ciphers.

然而,无论我做什么,Node.js 都会不断发送 TLS_EMPTY_RENEGOTIATION_INFO_SCSV 密码.我试图故意避免发送此密码来模仿 Firefox/Chrome 的 TLS 协商.

However, Node.js keeps sending the TLS_EMPTY_RENEGOTIATION_INFO_SCSV cipher no matter what I do. I'm trying to deliberately avoid sending this cipher to mimic the TLS negotiation of Firefox/Chrome.

这是我用来修改和检查节点发送的密码的代码:

Here's the code I use to modify and check which ciphers Node is sending:

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);
    }
});

有什么办法可以禁止在 Node.js 中发送这个密码?

Is there any way to disable sending this cipher in Node.js?

推荐答案

鉴于此问题与 Node.js 相关,有一种简单的方法可以处理您的问题,而无需深入研究:

Given that this issue is related to Node.js, there is one simple method to deal with your issue without actually digging to much into it:

在您的 Node.js 进程前面放置一个 Web 代理,让它处理完整的 SSL 连接.在 Node.js 代码本身中,您只会向本地 HTTP 服务器发送请求.

Put a web proxy in front of your Node.js process and let it handle the complete SSL connection. In the Node.js code itself, you would only send a request to a local HTTP server.

nginx 配置示例(在 http 指令内):

Example configuration with nginx (inside the http directive):

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;
   }
}

并将 nodejs 更改为:

And change the nodejs to:

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);
    }
});

不幸的是,虽然我确实这样做了,但结果是一样的:

Unfortunately though I actually did this, and the result was the same:

<代码> {" 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":真,session_ticket_supported":真,tls_compression_supported":假,unknown_cipher_suite_supported":假,beast_vuln":假,able_to_detect_n_minus_one_splitting",版本,密码"::TLS 1.2",评级":可能还好"}

这基本上意味着它可能是标准的 OpenSSL 行为.

This basically means that its probably standard OpenSSL behavior.

可以使用 SSL_CTX_set_options 在 OpenSSL 中设置一些选项

There are options which can be set in OpenSSL using SSL_CTX_set_options

这里特别有趣的是 SECURE RENEGOTIATION 部分和这个选项:

Especially interesting here is the SECURE RENEGOTIATION section and this option:

SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION

SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION

允许在 OpenSSL 和未打补丁的客户端或服务器之间进行传统的不安全重新协商.有关详细信息,请参阅安全重新协商部分.

Allow legacy insecure renegotiation between OpenSSL and unpatched clients or servers. See the SECURE RENEGOTIATION section for more details.

我不确定这是否真的阻止了重新协商密码的发送.如果此选项实际上是正确的,则可能有一种方法可以修补 Node.js 以使用该选项或使用该选项重新编译 OpenSSL.

I am not certain though if this actually prevents the renegotiation cipher from being send. If this option is actually correct, there might be a way to either patch Node.js to use that option or recompile OpenSSL with that option.

当然也可以选择使用未修补的旧版本.根据我的理解,虽然 TLS_EMPTY_RENEGOTIATION_INFO_SCSV 与 POODLE 无关,但来自较旧的修复:

There would of course also be the option to use an old unpatched version. From my understanding though TLS_EMPTY_RENEGOTIATION_INFO_SCSV is not related to POODLE, but from an older fix:

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.8c8b, 0.9.8a, 0.9.8)

CVE-2009-3555 (OpenSSL advisory) 5th November 2009:
Implement RFC5746 to address vulnerabilities in SSL/TLS renegotiation. Fixed in OpenSSL 0.9.8m (Affected 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 ……或者使用带有未打补丁的 OpenSSL 的 nginx 东西……

Modern Node.js comes with a statically linked OpenSSL however and does not support OpenSSL 0.9.8, so you would need an older version of Node.js regardless... or use the nginx stuff with an unpatched OpenSSL...

这就是我被卡住的地方.这不是一个完整的答案,但我认为它至少值得分享.

This is kind of where I am stuck. Its not really an complete answer, but I think its at least worth to share.

总而言之,我认为如果您想在不重新编译的情况下使用 nginx 和未打补丁的 OpenSSL,并配置多个服务器,为您想要模拟的每个客户端配置一个.

To sum it up though, I think if you want to do this without recompiling use nginx with and unpatched OpenSSL, and configure multiple servers, one for each client you want to mimic.

如果您需要在 node 中单独完成此操作,最好的办法是直接在那里修补 OpenSSL 并重新编译 node.

If you require this to be soley done in node, your best bet is to patch OpenSSL there directly and recompile node.

这篇关于避免在 TLS Client Hello 中发送 TLS_EMPTY_RENEGOTIATION_INFO_SCSV 密码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆