RUDE

Узел, получающий старый сертификат TLS

Я использовал следующий код, чтобы получить сертификат TLS сервера для stackoverflow.com:

const tls = require('tls');

const conn = tls.connect({
  host: 'stackoverflow.com',
  port: 443,
  rejectUnauthorized: false
}, () => {
  const cert = conn.getPeerCertificate(false);
  console.log(cert);
  conn.destroy();
});

Результат включает в себя следующее:

  • тема: { CN: '*.stackexchange.com' }
  • эмитент: { C: 'US', O: "Let's Encrypt", CN: 'R3' }
  • valid_from: Dec 3 14:00:52 2020 GMT
  • valid_to: Mar 3 14:00:52 2021 GMT
  • отпечаток пальца256: C6:D3:6E:68:38:EC...

Обратите внимание, что это сертификат с истекшим сроком действия.

Напротив, когда я посещаю stackoverflow.com в Firefox, он загружает сертификат со следующими данными:

  • Не раньше: Sun, 06 Mar 2022 14:17:27 GMT
  • Не после: Sat, 04 Jun 2022 14:17:26 GMT
  • SHA-256: 04:F7:14:2A:28:EF:1F...

Похоже, Node получает старый сертификат. Может быть, он где-то кешируется?

Моя платформа:

  • Узел v17.8.0
  • Linux, x64, Манджаро

1
26
1

Ответ:

Решено

Я получаю тот же недействительный сертификат с вашим исходным кодом, поэтому я взглянул на документация и обнаружил следующую интересную деталь:

Unlike the https API, tls.connect() does not enable the SNI (Server Name Indication) extension by default, which may cause some servers to return an incorrect certificate or reject the connection altogether. To enable SNI, set the servername option in addition to host.

Добавление опции servername:

const tls = require('tls');

const conn = tls.connect({
  host: 'stackoverflow.com',
  servername: 'stackoverflow.com',
  port: 443,
  rejectUnauthorized: false
}, () => {
  const cert = conn.getPeerCertificate(false);
  console.log(cert);
  conn.destroy();
});

Я получаю действующий сертификат:

subject: [Object: null prototype] { CN: '*.stackexchange.com' },
[...]
valid_from: 'Mar  6 14:17:27 2022 GMT',
valid_to: 'Jun  4 14:17:26 2022 GMT',
[...]