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
Aucune suite de chiffrement implémentée par rustls
fréquenteLes serveurs anciens limités aux suites à échange de clés RSA, aux suites CBC-SHA ou aux suites 3DES n’ont rien en commun avec rustls.
Le serveur ne parle que TLS 1.0 ou 1.1
fréquenterustls n’implémente pas les versions de TLS antérieures à la 1.2.
Le serveur exige un certificat client
occasionnelleEn TLS 1.2, les points de terminaison en TLS mutuel répondent par handshake_failure à un client qui n’a pas de certificat.
Comment corriger l’erreur
- 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.
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.
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()?;