Node.js 使用特定密码的 TLS 请求

Node.js TLS request with specific ciphers

我有一个 Node.js 应用需要检查外部资源的 TLS 兼容性。我需要限制 Node.js 在发出外部 TLS 请求时将使用的特定密码。我正在寻找实现此目的的示例代码。

更多信息:Apple 在 iOS9 all outbound connections be encrypted 中要求并且允许的密码列表是有限的。

接受的密码是:

TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA

我的目标是构建一项服务,该服务将检查以确保外部服务器满足 Apple 要求。

您可以使用该密码列表连接到每个资源。如果连接成功,那么您就知道正在使用其中一个密码,因此可以签出。可以通过 ciphers 属性 设置独占密码列表。例如:

var ciphers = ['TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384',
               'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256',
               'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384',
               'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA',
               'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256',
               'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA',
               'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384',
               'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256',
               'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384',
               'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256',
               'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA'].join(':');
tls.connect({
  host: 'example.com',
  port: 443,
  ciphers: ciphers
}, function() {
  // Success!
}).on('error', function(err) {
  // Unsuccessful! You may check `err` to make sure it wasn't an unexpected
  // error like ECONNREFUSED
});

您还可以通过在节点 v10.16.0 或更高版本中设置 secureProtocol 属性 或 minVersionmaxVersion 属性来限制使用的协议。例如,要使用 TLSv1.2:

var ciphers = ['TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384',
               'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256',
               'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384',
               'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA',
               'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256',
               'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA',
               'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384',
               'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256',
               'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384',
               'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256',
               'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA'].join(':');
tls.connect({
  host: 'example.com',
  port: 443,
  ciphers: ciphers,
  secureProtocol: 'TLSv1_2_method',
  // or for node v10.16.0+:
  //   minVersion: 'TLSv1.2',
  //   maxVersion: 'TLSv1.2',
}, function() {
  // Success!
}).on('error', function(err) {
  // Unsuccessful! You may check `err` to make sure it wasn't an unexpected
  // error like ECONNREFUSED
});