Перейти к содержимому
ecdsa.com
Node.js tls.connect / fetchМодуль crypto в Node.js

Сообщение об ошибке

code: 'ERR_SSL_SSL/TLS_ALERT_HANDSHAKE_FAILURE'

Также выводится как

  • ERR_SSL_SSL/TLS_ALERT_HANDSHAKE_FAILURE

Код повторяет строку причины из OpenSSL: релизы Node.js со встроенным OpenSSL 3.0 или 3.1 выдают ERR_SSL_SSLV3_ALERT_HANDSHAKE_FAILURE (от «sslv3 alert handshake failure»), а текущие релизы с OpenSSL 3.5 — ERR_SSL_SSL/TLS_ALERT_HANDSHAKE_FAILURE. При вызове https.request() то же оповещение о сбое рукопожатия выглядит как «write EPROTO … SSL alert number 40».

Node.js tls.connect / fetch — TLS alert 40 (handshake_failure) received from the server

Что это означает

Сервер ответил на ClientHello от Node.js оповещением TLS 40 (handshake_failure) и закрыл соединение. Он не нашёл приемлемого сочетания набора шифров, группы обмена ключами и алгоритма подписи либо требует клиентский сертификат, который не был отправлен. Node.js формирует код ошибки из текста причины в OpenSSL, поэтому в коде есть «SSL/TLS».

Почему это происходит

Как исправить

  1. 1.

    Сравните, что поддерживают обе стороны

    Выведите список шифров Node.js по умолчанию и перечислите наборы шифров сервера; если пересечений нет, сервер нужно обновить.

    bash
    node -p "require('tls').getCiphers().length + ' suites; default list: ' + require('tls').DEFAULT_CIPHERS"
    nmap --script ssl-enum-ciphers -p 443 api.example.com   # what the server accepts
  2. 2.

    Отправьте клиентский сертификат

    Задайте cert и key (или pfx) в агенте, через который идут запросы к эндпоинту с mTLS.

    js
    // Mutual TLS: present the client certificate the server requires
    import https from "node:https";
    import fs from "node:fs";
    
    const agent = new https.Agent({ cert: fs.readFileSync("client.pem"), key: fs.readFileSync("client.key") });
    https.get("https://mtls.example.com/", { agent }, (res) => res.resume());
  3. 3.

    Владельцам серверов: предлагайте современные наборы шифров

    Связка TLS 1.3 и TLS 1.2 с ECDHE и AES-GCM или ChaCha20-Poly1305 работает с любым поддерживаемым релизом Node.js.

    text
    # Server side (nginx): TLS 1.3 + TLS 1.2 ECDHE with AEAD ciphers
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;

Связанные ошибки

Открыть всю базу ошибок подписей