Zum Inhalt springen
ecdsa.com
Java (JSSE)Java

Fehlermeldung

javax.net.ssl.SSLHandshakeException: (handshake_failure) Received fatal alert: handshake_failure

Auch ausgegeben als

  • javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
  • Received fatal alert: handshake_failure

JDK 21 und neuer zeigen den Namen des Alerts in Klammern: „(handshake_failure) Received fatal alert: handshake_failure“; JDK 8 und 11 geben nur „Received fatal alert: handshake_failure“ aus.

Java (JSSE) — TLS alert 40 received from the server

Was der Fehler bedeutet

Der Server hat den TLS-Handshake mit dem Alert 40 (handshake_failure) abgebrochen. Entweder fand er im ClientHello der JVM nichts Akzeptables (keine gemeinsame Cipher Suite, keine gemeinsame Gruppe oder kein gemeinsamer Signaturalgorithmus), oder er verlangt ein Client-Zertifikat, das die JVM nicht vorgelegt hat. Java meldet nur, dass der Alert eingetroffen ist; der Grund steht im Log des Servers oder wird mit javax.net.debug sichtbar.

Warum der Fehler auftritt

So behebst du den Fehler

  1. 1.

    Handshake ansehen

    javax.net.debug=ssl:handshake gibt das ClientHello (angebotene Suites) und den Alert aus; -XshowSettings:security:tls listet die im JDK aktivierten Protokolle und Suites auf.

    bash
    # Show what the JVM offers and how the handshake ends
    java -Djavax.net.debug=ssl:handshake -jar app.jar 2>&1 | grep -E 'ClientHello|cipher_suites|Alert|fatal'
    # Settings in effect (protocols, suites) for this JDK
    java -XshowSettings:security:tls -version
  2. 2.

    Eigener Server: aktuelle Suites aktivieren

    TLS 1.3 und TLS 1.2 mit ECDHE und AES-GCM oder ChaCha20 funktionieren mit jedem gepflegten JDK.

    text
    # Server side: offer ECDHE + AEAD suites that current JDKs support
    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;
  3. 3.

    Mutual TLS: Client-Keystore konfigurieren

    javax.net.ssl.keyStore (oder ein SSLContext, der aus einer KeyManagerFactory gebaut wird) liefert das Client-Zertifikat.

    bash
    # Mutual TLS: give the JVM the client certificate and key
    java -Djavax.net.ssl.keyStore=client.p12 -Djavax.net.ssl.keyStorePassword=changeit \
         -Djavax.net.ssl.keyStoreType=PKCS12 -jar app.jar
  4. 4.

    Letzter Ausweg: disabledAlgorithms für einen einzelnen Legacy-Client anpassen

    Eine Override-Datei, die du mit -Djava.security.properties übergibst, kann TLS_RSA_* für eine einzelne JVM aus jdk.tls.disabledAlgorithms entfernen; kopiere den vollständigen Standardwert und entferne nur das, was nötig ist. Diesen Suites fehlt Forward Secrecy, halte die Ausnahme also eng begrenzt und befristet.

    bash
    # Last resort for one legacy server: take this JDK's own value and drop only TLS_RSA_*
    v=$(sed -n '/^jdk.tls.disabledAlgorithms=/,/[^\\]$/p' "$JAVA_HOME/conf/security/java.security" | sed 's/\\$//' | tr -d '\n')
    printf '%s\n' "$v" | sed -E 's/, TLS_RSA_\*//' > legacy-rsa.security
    java -Djava.security.properties=legacy-rsa.security -jar legacy-client.jar

Verwandte Fehler

Gesamte Signaturfehler-Datenbank durchsuchen