Aller au contenu
ecdsa.com
curl (OpenSSL backend)curl

Message d’erreur

curl: (35) TLS connect error: error:0A000410:SSL routines::ssl/tls alert handshake failure

Également affiché sous la forme

  • curl: (35) error:0A000410:SSL routines::sslv3 alert handshake failure
  • curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure

OpenSSL 3.3 et les versions ultérieures formulent la raison « ssl/tls alert handshake failure » ; OpenSSL 3.1 et les versions antérieures affichent « sslv3 alert handshake failure » (1.1.1 avec le code 14094410 et le nom de fonction ssl3_read_bytes). Les versions récentes de curl ajoutent « TLS connect error: » devant.

curl (OpenSSL backend) — CURLE_SSL_CONNECT_ERROR, TLS alert 40 (handshake_failure) received from the server

Ce que cela signifie

Le serveur a mis fin au handshake en envoyant l’alerte TLS 40 (handshake_failure) : il n’a pas pu s’accorder sur des paramètres avec ce que proposait curl. L’alerte n’indique aucune raison, si bien que la cause réelle n’apparaît que dans les journaux du serveur ; côté client, vous pouvez seulement comparer ce que chaque partie prend en charge. À ce stade, le certificat n’avait pas encore été vérifié.

Pourquoi cela se produit

Comment corriger l’erreur

  1. 1.

    Comparer ce que proposent les deux parties

    Énumérez les suites et les versions de protocole du serveur, puis comparez-les avec la liste de chiffrements du client. La sortie en mode verbeux de curl montre jusqu’où le handshake est allé et quelle version a été tentée.

    bash
    # What the server accepts (needs nmap) and what this client offers
    nmap --script ssl-enum-ciphers -p 443 api.example.com
    openssl ciphers -v 'DEFAULT' | head -20
    # Full handshake trace from curl's side
    curl -sv https://api.example.com/ -o /dev/null 2>&1 | grep -E '^\* (TLS|SSL)'
  2. 2.

    Propriétaires de serveurs : utiliser une configuration de chiffrement actuelle

    Proposez TLS 1.3 et TLS 1.2 avec des suites ECDHE et AEAD (AES-GCM, ChaCha20-Poly1305). Tous les clients de la dernière décennie les prennent en charge, et aucun logiciel moderne n’a besoin de l’échange de clés RSA ni de CBC.

    text
    # nginx: TLS 1.2 with forward-secret AEAD suites + TLS 1.3
    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:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_prefer_server_ciphers off;
  3. 3.

    Envoyer le bon nom de serveur

    Utilisez le nom d’hôte dans l’URL, ou conservez le nom tout en forçant une adresse avec --resolve. Avec openssl s_client, passez -servername lorsque vous vous connectez à une adresse IP.

    bash
    # Use the host name in the URL (SNI is sent automatically); for IP targets keep the name:
    curl --resolve api.example.com:443:203.0.113.10 https://api.example.com/
    # openssl s_client sends SNI only with -servername (or a host name in -connect)
    openssl s_client -connect 203.0.113.10:443 -servername api.example.com </dev/null
  4. 4.

    Présenter le certificat client pour le TLS mutuel

    Si le point de terminaison est une API mTLS, configurez le certificat client et sa clé ; les journaux du serveur décriront le problème comme un certificat de pair absent ou impossible à vérifier.

    bash
    # Mutual TLS: present the client certificate and key the server expects
    curl --cert client.pem --key client.key https://mtls.example.com/

Erreurs associées

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