Zum Inhalt springen
ecdsa.com
rustls (via reqwest, ureq, tonic)Rust

Fehlermeldung

received fatal alert: HandshakeFailure

reqwest gibt die Meldung am Ende seiner Fehlerkette aus, ureq als „io: received fatal alert: HandshakeFailure“. Gegen einen Server, der nur TLS 1.0 spricht (tls-v1-0.badssl.com), hat unser rustls-Client genau diesen Alert erhalten. Andere Alerts erscheinen mit ihren eigenen rustls-Namen nach „received fatal alert: “.

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

Was der Fehler bedeutet

Der Server hat das ClientHello von rustls mit dem TLS-Alert 40 (handshake_failure) beantwortet. rustls implementiert bewusst nur modernes TLS: TLS 1.2 und 1.3 mit ECDHE-Schlüsselaustausch und AEAD-Verschlüsselungsverfahren. Server, die RSA-Schlüsselaustausch, CBC-Suites, TLS 1.0/1.1 oder ein Client-Zertifikat verlangen, weisen rustls auf diese Weise ab.

Warum der Fehler auftritt

So behebst du den Fehler

  1. 1.

    Prüfen, was der Server anbietet

    Bietet der Server keine Suite mit ECDHE + AEAD an, muss er modernisiert werden.

    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.

    Letzter Ausweg für einen nicht mehr wartbaren Altserver: native-tls

    Ein eigener Client, gebaut mit dem Feature native-tls von reqwest, verwendet die TLS-Bibliothek der Plattform (unter Linux OpenSSL, dessen Entwicklungs-Header zum Bauen nötig sind), und diese Bibliothek erlaubt je nach Systemrichtlinie womöglich noch ältere Suites. Setze diesen Client nur für den alten Endpunkt ein; die schwache Konfiguration des Servers bleibt ein Risiko.

    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.

    Mutual TLS: Client-Zertifikat vorlegen

    reqwest::Identity::from_pem mit einem PEM, das Zertifikat und privaten Schlüssel enthält, am Builder gesetzt.

    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()?;

Verwandte Fehler

Gesamte Signaturfehler-Datenbank durchsuchen