节点js https minDHSize不关闭连接
node js https minDHSize not closing connection
我正在向提供 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 连接尚未关闭。
我错过了什么?
There is no message coming from the client to indicate a handshake failure and the TCP connection has not been closed.
这样的握手不会失败。 OpenSSL 无法在密钥交换中要求最小经典 DH 大小(对于 DHE 和 OpenSSL 调用 ADH 的 DH_anon),因此 nodejs 在 after 之后实施此限制OpenSSL 完成握手 但在允许任何数据通过之前——因为它也对服务器证书名称检查进行,OpenSSL 最初没有实现,现在实现与 nodejs 选择的不同。参见 onSecureConnect
in _tls_wrap.js
。
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/anon 组,现在称为 FFDHE 以区别于 ECDHE,客户端可以以前 supported_curves 扩展名的请求现在被重新调整为 supported_groups (特别是它可能需要 4096),但是 OpenSSL 和 nodejs 没有实现这个选项。在 1.3 中 supported_groups 是必需的,但 FFDHE 组不是必需的,甚至不是特别鼓励的,而且 AFAICT OpenSSL 也不(还?)在那里支持它们——而且无论如何 1.3 不允许 'anon'根本。 (* 7919 正式适用于 1.1 和 1.0,但我无法想象任何实现包括 7919 而不是 1.2,因此您永远不需要更低的协议。)
我正在向提供 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 连接尚未关闭。
我错过了什么?
There is no message coming from the client to indicate a handshake failure and the TCP connection has not been closed.
这样的握手不会失败。 OpenSSL 无法在密钥交换中要求最小经典 DH 大小(对于 DHE 和 OpenSSL 调用 ADH 的 DH_anon),因此 nodejs 在 after 之后实施此限制OpenSSL 完成握手 但在允许任何数据通过之前——因为它也对服务器证书名称检查进行,OpenSSL 最初没有实现,现在实现与 nodejs 选择的不同。参见 onSecureConnect
in _tls_wrap.js
。
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/anon 组,现在称为 FFDHE 以区别于 ECDHE,客户端可以以前 supported_curves 扩展名的请求现在被重新调整为 supported_groups (特别是它可能需要 4096),但是 OpenSSL 和 nodejs 没有实现这个选项。在 1.3 中 supported_groups 是必需的,但 FFDHE 组不是必需的,甚至不是特别鼓励的,而且 AFAICT OpenSSL 也不(还?)在那里支持它们——而且无论如何 1.3 不允许 'anon'根本。 (* 7919 正式适用于 1.1 和 1.0,但我无法想象任何实现包括 7919 而不是 1.2,因此您永远不需要更低的协议。)