node js https minDHSize未关闭连接



我正在向提供2048位Diffie-Hellman密码的服务器发出https请求,并试图让我的代码拒绝连接并向服务器发出握手失败并关闭连接。我不认为它被使用,但我在客户端有一个4096位DH密钥,如果服务器也使用4096位DH密钥,连接是完美的。

const dhparam = fs.readFileSync( "dhparam_4096.pem" );
const data = JSON.stringify({ 
part1 : "Hello", 
part2 " "Name" });
const httpsOptions = {
host : address + "%" + Ethernet.GetIfaceName(),
port : service.port,
path : service.txt.path,
method : "PUT",
rejectUnauthorized : false,
ciphers : "ADH-AES256-GCM-SHA384:@SECLEVEL=0",
dhparam,
minDHSize : 4096,
headers : { 
'Content-Type' : 'application/json',
'Content-Length' : data.length,
},
servername : "nameServer",
}
console.log( "    httpsOptions =", httpsOptions );

/*** Send the request ***/

var req = https.request( httpsOptions, res => 
{
var data = "";
res.on( 'data', d => data += d );
res.on( 'end', d =>  
{ 
if ( d ) data += d;
console.log( "Received data =", data );
console.log( "    ", data.toString() );
});
console.log( "response =", res.statusCode, res.statusMessage );
});
req.on( "error", err => 
{
console.log( "error =", err.code );
if ( err.code === "ERR_TLS_DH_PARAM_SIZE" )
{
console.log("    DH Key is not 4096 bits" );
req.socket.destroy();
}

});
console.log( "    sending data: ". data );
req.write( data );
req.end();

minDHSize: 4096导致错误事件被触发,因此我知道检测机制正在工作。

我在这个路径中有一个socket.destroy(),但这似乎不起作用。

在服务器上,我启用了跟踪,并得到以下结果:
Received Record
Header:
Version = TLS 1.0 (0x301)
Content Type = Handshake (22)
Length = 153
ClientHello, Length=149
client_version=0x303 (TLS 1.2)
Random:
gmt_unix_time=0xFE471FB1
random_bytes (len=28): 3B54266D9E916B151A9A8E940EE4D0BEE0E59C1F2693B6E637CC4D
session_id (len=0): 
cipher_suites (len=4)
{0x00, 0xA7} TLS_DH_anon_WITH_AES_256_GCM_SHA384
{0x00, 0xFF} TLS_EMPTY_RENEGOTIATION_INFO_SCSV
compression_methods (len=1)
No Compression (0x00)
extensions, length = 104
extension_type=server_name(0), length=36
extension_type=session_ticket(35), length=0
extension_type=encrypt_then_mac(22), length=0
extension_type=extended_master_secret(23), length=0
extension_type=signature_algorithms(13), length=48
ecdsa_secp256r1_sha256 (0x0403)
ecdsa_secp384r1_sha384 (0x0503)
ecdsa_secp521r1_sha512 (0x0603)
ed25519 (0x0807)
ed448 (0x0808)
rsa_pss_pss_sha256 (0x0809)
rsa_pss_pss_sha384 (0x080a)
rsa_pss_pss_sha512 (0x080b)
rsa_pss_rsae_sha256 (0x0804)
rsa_pss_rsae_sha384 (0x0805)
rsa_pss_rsae_sha512 (0x0806)
rsa_pkcs1_sha256 (0x0401)
rsa_pkcs1_sha384 (0x0501)
rsa_pkcs1_sha512 (0x0601)
ecdsa_sha224 (0x0303)
ecdsa_sha1 (0x0203)
rsa_pkcs1_sha224 (0x0301)
rsa_pkcs1_sha1 (0x0201)
dsa_sha224 (0x0302)
dsa_sha1 (0x0202)
dsa_sha256 (0x0402)
dsa_sha384 (0x0502)
dsa_sha512 (0x0602)

Sent Record
Header:
Version = TLS 1.2 (0x303)
Content Type = Handshake (22)
Length = 57
ServerHello, Length=53
server_version=0x303 (TLS 1.2)
Random:
gmt_unix_time=0xDB67568F
random_bytes (len=28): BF81EBFB16471C15ED8D7D0D5273232CFBD6E70E933CC00747B57899
session_id (len=0): 
cipher_suite {0x00, 0xA7} TLS_DH_anon_WITH_AES_256_GCM_SHA384
compression_method: No Compression (0x00)
extensions, length = 13
extension_type=renegotiate(65281), length=1
<EMPTY>
extension_type=session_ticket(35), length=0
extension_type=extended_master_secret(23), length=0
Sent Record
Header:
Version = TLS 1.2 (0x303)
Content Type = Handshake (22)
Length = 523
ServerKeyExchange, Length=519
KeyExchangeAlgorithm=DHE
dh_p (len=256):     C0C8B68E3EAADEB2ECCA8863B8017D63D3259FEC711A97D84E8100DC427BA45684DF962C00C8116DCE797BD02CA3D02FB2C01F7F212AA1E899CB108A57156841A1CE40F4E2EF65AC1598964851F4DB874BD9E8031B2467B7624CE3CC950B0167C23A91896CAF44199B45A046A9EA1D274D6545AC1AC11542ED9F1C0CA3F8DDF5CB215436C3416FFE20242AA5C3270858D07314C58478F771D201B54D47DFAFD87F127FC3E8C11F40CE5B1A063AF7C6C50347C3049A9EE479EA685499E57A49DE1287DC96AE71E0E7F10B42BB09DC8BAFBE96F710FE20F0FC296C1D951CD258946E1AEF5876494B524809B14F12F393B40AEF0BD4E44F6E67E8A579184CAB393B
dh_g (len=1): 02
dh_Ys (len=256): AE3E9B2D557F7A862D323911B17061471865880B8CDA469D94CCEC11A74B6C081A2F0389BF2B961E5A54C7A6DE41D1AFB9388B5BB51EC6F129BA093A83DA68288D5246869B52B54D2CF5CD0F1BDEAA206FC7C680B02B18903969B061817479545BF8EA17901CF86A9E580DF860FD29E25A2EB56D00FE319D2DA17F9E3F33986D4716D86882E76E774A7CB717AD08E60AA182843B139E6EFB63F2EFCD6E351503352F3E5A23D397AAA4BB359A8EF125FF10FE20805B083B15135247E1B08F57B3B43EF13E9B60EEB2EB1743466DD10922ABD588E9031BC1BDF10353484BC10B2E32D24E513E58092373E96360836BE4FFDC3395CB4044BCEE11248E0E5EDA412F
Sent Record
Header:
Version = TLS 1.2 (0x303)
Content Type = Handshake (22)
Length = 4
ServerHelloDone, Length=0
Received Record
Header:
Version = TLS 1.2 (0x303)
Content Type = Handshake (22)
Length = 262
ClientKeyExchange, Length=258
KeyExchangeAlgorithm=DHE
dh_Yc (len=256): 060D2565ABCE52B7480CB72D2DEF6F5B8FC25B15FB070BB97DC0B509143CFC562BF8483D24959B8192B292DE1D17FBEB281734DF062F48313AEBE3F1398EC9C535086D3DBDB7F2F52FB1F656B078908520B2B2285F2382C16E0731AAF00CAF098EBB32AE89CEB50940BA1EBE8A08EF86739CFC6DABD9965E9D2325DA73F53045C686C74006A525A35E27180D51BED9EEB9831EF617C7D78AF19CCBB6EE9F016911E1C2F0D9CEF6F3E31E14109EFDBF1187720AA34324C94CB166DAAA4D2E69D1182D5B86C8F1EA89FB02C5E9420DFC333ABBA4050F8C782F1B16B74F87F0251B06B4D725FC6FE26B3FC5C2CB54FBA94174576F694A02D1FC707BABD2E03FB854
Received Record
Header:
Version = TLS 1.2 (0x303)
Content Type = ChangeCipherSpec (20)
Length = 1
Received Record
Header:
Version = TLS 1.2 (0x303)
Content Type = Handshake (22)
Length = 40
Finished, Length=12
verify_data (len=12): DCA9352457FDBF48674FE0B8
Sent Record
Header:
Version = TLS 1.2 (0x303)
Content Type = Handshake (22)
Length = 202
NewSessionTicket, Length=198
ticket_lifetime_hint=7200
ticket (len=192): 06B807C486272F454FC553528EC5B6932A5989321D4171F7A6DAF4A2F0E9FA9A3620F9F90499FF5FD7C2566D4A5E7574DD6863353CC428E7656168799B3501613A67AF605746F034571AA9264A53A3DCCE4CACCB72FA54FF9B4C735666F4FA0AEC56A6F8819E375BEC01DC9FC282052E4FBFF88D07596247CE2AC92870B4CE759D946FD18E78B48EBF4474F9D6D51BB6924662B9CB3A312E9D7AD76B97C335A07531841F2D7A5A02BCBCE4857EE43626FF07CD4D44937CFF74401FFE2787740C
Sent Record
Header:
Version = TLS 1.2 (0x303)
Content Type = ChangeCipherSpec (20)
Length = 1
change_cipher_spec (1)
Sent Record
Header:
Version = TLS 1.2 (0x303)
Content Type = Handshake (22)
Length = 40
Finished, Length=12
verify_data (len=12): E72603E1A716815F94F9AAEE
Sent Record
Header:
Version = TLS 1.2 (0x303)
Content Type = Alert (21)
Length = 26
Level=warning(1), description=close notify(0)

没有来自客户端的消息表明握手失败,TCP连接尚未关闭。

我错过了什么?

没有来自客户端的消息表明握手失败,TCP连接尚未关闭。

这样握手就不会失败。OpenSSL没有在密钥交换中要求最小的经典dh大小(对于DHE和DH_anon, OpenSSL称为ADH),因此nodejs在 OpenSSL完成握手之后强制执行此限制但在允许任何数据通过之前-因为它也用于服务器证书名称检查,OpenSSL最初没有实现,现在实现与nodejs选择的不同。参见_tls_wrap.js中的onSecureConnect

TCP连接已关闭,这可能是为什么你的服务器正在发送close_notify-或试图;由于TCP关闭,这个发送实际上会失败。我测试的服务器(OpenSSL和Java)都显示TCP从(nodejs)客户端关闭,尽管OpenSSL隐式地这样做(读取计数为0),并且它们的响应不同:只有旧的Java 8(在8u261中向后移植新的11堆栈之前)试图在'response'中发送close_notify。我怀疑你的服务器只是没有记录TCP关闭;尝试使用外部工具,如wireshark或类似工具。

为了明确,您在客户端中设置了4096位DH参数,而不是密钥。在服务器端只设置参数;两端的密钥是每次握手(在参数定义的子组中)生成的,这就是为什么它们被称为短暂的。并且(用户选择的)在客户端中设置的DH参数将被忽略(但参见下一节)。

仅供参考:有一个相当新的协议选项,RFC7919,用于TLS1.2*使用标准化(不是用户选择的)DHE/匿名组,现在称为FFDHE以区别于ECDHE,客户端可以使用以前的supported_curves扩展请求,现在被重新利用为supported_groups(特别是它可能需要4096),但OpenSSL和因此nodejs不实现此选项。在1.3中,supported_groups是必需的,但是FFDHE组不是必需的,甚至不是特别鼓励的,而且AFAICT OpenSSL也不支持它们——无论如何1.3根本不允许"匿名"。(*形式上,7919也适用于1.1和1.0,但我无法想象任何实现包括7919而不包括1.2,所以你永远不需要更低的协议。)

最新更新