Aller au contenu
ecdsa.com
rustls (via reqwest, ureq, tonic)Rust

Message d’erreur

received fatal alert: HandshakeFailure

reqwest l’affiche à la fin de sa chaîne d’erreurs, ureq sous la forme « io: received fatal alert: HandshakeFailure ». Face à un serveur limité à TLS 1.0 (tls-v1-0.badssl.com), notre client rustls a reçu cette même alerte. Les autres alertes apparaissent sous leur propre nom rustls après « received fatal alert: ».

rustls (via reqwest, ureq, tonic) — rustls::Error::AlertReceived(HandshakeFailure)

Ce que cela signifie

Le serveur a répondu au ClientHello de rustls par l’alerte TLS 40 (handshake_failure). rustls n’implémente délibérément que le TLS moderne : TLS 1.2 et 1.3 avec échange de clés ECDHE et algorithmes de chiffrement AEAD. Les serveurs qui exigent un échange de clés RSA, des suites CBC, TLS 1.0/1.1 ou un certificat client le refusent de cette façon.

Pourquoi cela se produit

Comment corriger l’erreur

  1. 1.

    Vérifier ce que propose le serveur

    S’il ne propose aucune suite ECDHE + AEAD, le serveur doit être modernisé.

    bash
    # What does the server accept? rustls offers TLS 1.2/1.3 with ECDHE + AES-GCM or ChaCha20 only
    nmap --script ssl-enum-ciphers -p 443 legacy.example.com
  2. 2.

    En dernier recours pour un serveur ancien impossible à maintenir : native-tls

    Un client dédié construit avec la fonctionnalité native-tls de reqwest utilise la bibliothèque TLS de la plateforme (OpenSSL sous Linux, dont les en-têtes de développement sont nécessaires à la compilation), et cette bibliothèque peut encore autoriser des suites plus anciennes, sous réserve de la politique du système. Limitez son usage au point de terminaison ancien ; la configuration faible du serveur reste un risque.

    toml
    # A legacy server you cannot upgrade: build a separate client on the OS TLS library
    # (OpenSSL on Linux), which still implements older suites. Cargo.toml:
    reqwest = { version = "=0.13.5", default-features = false, features = ["native-tls", "blocking"] }
  3. 3.

    TLS mutuel : présenter un certificat client

    reqwest::Identity::from_pem, avec un PEM contenant le certificat et la clé privée, appliqué au builder.

    rust
    // Mutual TLS with rustls: present a client certificate (PEM with certificate + private key)
    let identity = reqwest::Identity::from_pem(&std::fs::read("client-cert-and-key.pem")?)?;
    let client = reqwest::Client::builder().identity(identity).build()?;

Erreurs associées

Parcourir toute la base de données des erreurs de signature