Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js TLS request with specific ciphers

I have a Node.js app that needs to check the TLS compatibility of external resources. I need to limit the specific ciphers that Node.js will use when making an external TLS request. I'm looking for sample code to achieve this.

More info: Apple is requiring in iOS 9 all outbound connections be encrypted and the allowed cipher list is limited.

The accepted ciphers are:

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

My goal is to build a service that will check to make sure external servers meet the Apple requirements.

like image 762
Brent Avatar asked Feb 10 '23 09:02

Brent


1 Answers

You could just connect to each resource using that list of ciphers. If the connection is successful, then you know one of those ciphers is being used and thus checks out. An exclusive list of ciphers can be set via the ciphers property. For example:

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

You can also limit the protocol used by setting the secureProtocol property or the minVersion and maxVersion properties in node v10.16.0 or newer. For example, to use 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
});
like image 74
mscdex Avatar answered Feb 12 '23 07:02

mscdex