Comment HTTPS et TLS fonctionnent réellement : guide pratique
Pourquoi HTTPS est important et ce qu'il fait vraiment
Vous avez probablement vu l'icône de cadenas dans votre navigateur et supposé que votre connexion est sécurisée. Mais que garantit réellement ce cadenas ? HTTPS (Hypertext Transfer Protocol Secure) est HTTP superposé à TLS (Transport Layer Security). Il offre trois garanties fondamentales : confidentialité (les oreilles indiscrètes ne peuvent pas lire les données), intégrité (les données ne peuvent pas être modifiées en transit sans détection) et authentification (vous parlez au vrai serveur, pas à un imposteur).
Sans HTTPS, quiconque sur le chemin du réseau—le Wi-Fi d'un café, votre fournisseur d'accès ou un routeur malveillant—peut lire ou altérer votre trafic. Avec HTTPS, cela devient impraticable. Mais TLS n'est pas magique ; c'est un protocole soigneusement conçu avec des étapes spécifiques. Comprendre ces étapes vous aide à déboguer les problèmes de connexion, à configurer correctement les serveurs et à éviter les pièges courants.
Le handshake TLS : étape par étape
Lorsque votre navigateur se connecte à un site HTTPS, il effectue un handshake TLS avant tout échange de données HTTP. Voici ce qui se passe dans un handshake TLS 1.3 typique (la norme moderne) :
- ClientHello : Le client envoie un message avec les versions TLS prises en charge, les suites de chiffrement et une valeur aléatoire (client random). Il inclut également un partage de clé pour l'échange de clés (par exemple, via ECDHE).
- ServerHello : Le serveur répond avec la version TLS choisie, la suite de chiffrement, une valeur aléatoire (server random) et son propre partage de clé. Il envoie également sa chaîne de certificats.
- Vérification du certificat : Le client valide le certificat du serveur par rapport aux autorités de certification racines de confiance, vérifie le nom d'hôte et s'assure qu'il n'a pas expiré ou été révoqué.
- Dérivation de clé : Les deux parties calculent le même secret partagé à l'aide de leurs clés privées et des partages de clés échangés. À partir de cela, elles dérivent des clés de session symétriques.
- Finished : Les deux parties envoient un message Finished chiffré avec les clés de session pour vérifier l'intégrité du handshake.
Après le handshake, toutes les données applicatives (requêtes et réponses HTTP) sont chiffrées avec les clés de session symétriques. TLS 1.3 réduit le handshake à un aller-retour (1-RTT) et prend en charge la reprise 0-RTT pour les connexions répétées, améliorant ainsi la latence.
Certificats et chaînes de confiance
Un certificat est un document numérique qui lie une clé publique à une identité (comme un nom de domaine). Il est signé par une autorité de certification (CA). Votre navigateur et votre système d'exploitation disposent d'un magasin d'autorités racines de confiance. Lorsqu'un serveur présente son certificat, le client construit une chaîne depuis le certificat du serveur jusqu'à une racine de confiance. Si un maillon est manquant ou invalide, la connexion échoue.
Les problèmes courants de certificat incluent :
- Certificat expiré : La période de validité est dépassée.
- Incohérence de nom d'hôte : Le certificat est pour un domaine différent (par exemple,
example.comvswww.example.com). - Chaîne incomplète : Le serveur n'a pas envoyé les certificats intermédiaires, donc le client ne peut pas construire un chemin vers une racine de confiance.
- Émetteur non fiable : Le certificat est auto-signé ou provient d'une CA qui n'est pas dans le magasin de confiance.
Des outils comme OpenSSL peuvent vous aider à inspecter les certificats. Par exemple, pour afficher la chaîne de certificats qu'un serveur envoie :
openssl s_client -connect example.com:443 -showcerts
Cette commande affiche les certificats et le résultat de la vérification. Recherchez Verify return code: 0 (ok) pour confirmer que la chaîne est valide.
Débogage des connexions TLS
Lorsque HTTPS échoue, le message d'erreur indique souvent la phase qui a échoué. Voici un tableau de dépannage rapide :
| Symptôme | Cause probable | Action |
|---|---|---|
| Le navigateur affiche « certificat expiré » | Certificat dont la date d'expiration est dépassée | Renouvelez le certificat et rechargez le serveur |
| « NET::ERR_CERT_COMMON_NAME_INVALID » | Incohérence de nom d'hôte | Assurez-vous que le certificat couvre le domaine exact (y compris www si nécessaire) |
| « unable to get local issuer certificate » | Certificats intermédiaires manquants | Configurez le serveur pour envoyer la chaîne complète |
| Le handshake échoue avec une erreur de protocole | Le client et le serveur n'ont pas de version TLS ou de chiffrement commun | Mettez à jour la configuration du serveur pour prendre en charge TLS moderne (1.2+) |
Pour une inspection plus approfondie, utilisez openssl s_client avec des options comme -tls1_3 pour tester des versions spécifiques, ou curl -v https://example.com pour voir les détails du handshake. Les outils de développement du navigateur (onglet Sécurité) affichent également les informations sur le certificat et les détails de connexion.
Bonnes pratiques pour la configuration du serveur
Une configuration TLS appropriée est cruciale pour la sécurité et les performances. Suivez ces directives :
- Utilisez uniquement TLS 1.3 et 1.2 : Désactivez les versions plus anciennes (TLS 1.0, 1.1) qui ont des vulnérabilités connues.
- Activez HTTP/2 ou HTTP/3 : Ces protocoles nécessitent TLS et offrent des avantages en termes de performances.
- Utilisez des suites de chiffrement fortes : Préférez les chiffrements AEAD comme AES-GCM ou ChaCha20-Poly1305.
- Activez l'agrafage OCSP : Réduit la latence et améliore la confidentialité pour les vérifications de révocation.
- Implémentez HSTS : L'en-tête
Strict-Transport-Securityindique aux navigateurs d'utiliser toujours HTTPS pour votre domaine. - Automatisez le renouvellement des certificats : Utilisez Let's Encrypt avec Certbot ou similaire pour éviter l'expiration.
Voici un extrait de configuration Nginx pour TLS moderne :
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
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';
ssl_prefer_server_ciphers off;
add_header Strict-Transport-Security "max-age=63072000" always;
}
Après avoir appliqué les modifications, testez votre configuration avec des outils comme SSL Labs' SSL Test (en ligne) ou openssl s_client pour vérifier le handshake et la chaîne de certificats.
FAQ
Quelle est la différence entre TLS et SSL ?
SSL (Secure Sockets Layer) est le prédécesseur de TLS. Les versions SSL 2.0 et 3.0 sont obsolètes en raison de failles de sécurité. TLS 1.2 et 1.3 sont les protocoles modernes et sécurisés. Les gens disent souvent « SSL » familièrement, mais ils parlent de TLS.
Comment HTTPS protège-t-il contre les attaques de l'homme du milieu ?
HTTPS utilise des certificats signés par des CA de confiance pour authentifier le serveur. Pendant le handshake, le client vérifie le certificat du serveur et s'assure que la clé publique du certificat correspond à celle utilisée dans l'échange de clés. Cela empêche un attaquant d'usurper l'identité du serveur sans un certificat valide.
Puis-je utiliser HTTPS sans certificat ?
Non. Un certificat est requis pour que le serveur prouve son identité et pour que le client établisse un canal chiffré. Vous pouvez utiliser un certificat auto-signé pour les tests, mais les navigateurs afficheront un avertissement car il n'est pas approuvé par les CA publiques. Pour la production, utilisez un certificat d'une CA de confiance comme Let's Encrypt.
Lorsque vous travaillez avec des configurations TLS, vous pourriez avoir besoin d'inspecter les journaux du serveur ou de tester des points de terminaison. Pour une analyse rapide des journaux d'accès Nginx afin de repérer les erreurs TLS ou les modèles inhabituels, essayez l'Analyseur de journaux Nginx pour analyser et visualiser les données de journal sans effort.