Aller au contenu
ecdsa.com
Java (JSSE)Java

Message d’erreur

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

Également affiché sous la forme

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

À partir du JDK 21, le nom de l’alerte apparaît entre parenthèses : « (handshake_failure) Received fatal alert: handshake_failure » ; les JDK 8 et 11 affichent seulement « Received fatal alert: handshake_failure ».

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

Ce que cela signifie

Le serveur a interrompu le handshake TLS avec l’alerte 40 (handshake_failure). Soit il n’a rien trouvé d’acceptable dans le ClientHello de la JVM (aucune suite de chiffrement, aucun groupe ni aucun algorithme de signature en commun), soit il exige un certificat client que la JVM n’a pas présenté. Java signale seulement l’arrivée de l’alerte ; la raison figure dans le journal du serveur ou devient visible avec javax.net.debug.

Pourquoi cela se produit

Comment corriger l’erreur

  1. 1.

    Examiner le handshake

    javax.net.debug=ssl:handshake affiche le ClientHello (suites proposées) et l’alerte ; -XshowSettings:security:tls liste les protocoles et les suites activés dans le JDK.

    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.

    Propriétaires de serveurs : activer des suites actuelles

    TLS 1.3 et TLS 1.2 avec ECDHE et AES-GCM ou ChaCha20 fonctionnent avec tous les JDK maintenus.

    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.

    TLS mutuel : configurer le magasin de clés du client

    javax.net.ssl.keyStore (ou un SSLContext construit à partir d’une KeyManagerFactory) fournit le certificat client.

    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.

    En dernier recours : ajuster disabledAlgorithms pour un seul client ancien

    Un fichier de surcharge passé avec -Djava.security.properties peut retirer TLS_RSA_* de jdk.tls.disabledAlgorithms pour une seule JVM ; copiez la valeur par défaut complète et ne retirez que ce dont vous avez besoin. Ces suites n’offrent pas de confidentialité persistante : gardez donc l’exception ciblée et temporaire.

    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

Erreurs associées

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