2.3 — Sécurité du transport (TLS)
🎯 Objectif : comprendre ce qui se passe pendant le TLS handshake, ce qu’est un certificat, et comment configurer HTTPS proprement (HSTS, redirections, mixed content).
À l'issue de cet axe, tu sauras :
- Expliquer ce qui se passe pendant un TLS handshake
- Lire un certificat X.509 et identifier émetteur, sujet, validité
- Mettre en place Let's Encrypt en 5 minutes avec Caddy ou Certbot
- Configurer HSTS, redirection HTTP → HTTPS, mixed content
- Comprendre les types de certificats (DV, OV, EV) et choisir
Débutant
Pourquoi HTTPS ?
Section intitulée « Pourquoi HTTPS ? »HTTP en clair signifie que tout le monde sur le chemin (Wi-Fi public, FAI, gouvernement) peut :
- Lire ton trafic (mots de passe, cookies, données).
- Modifier les pages reçues (injecter des pubs, du malware).
- Usurper l’identité de sites populaires.
HTTPS = HTTP encapsulé dans TLS. Ça apporte :
- Confidentialité (chiffrement) : personne ne peut lire.
- Intégrité (HMAC) : personne ne peut modifier sans être détecté.
- Authentification (certificat) : tu parles bien au vrai serveur.
TLS Handshake (la version simple)
Section intitulée « TLS Handshake (la version simple) »Avant d’envoyer la moindre requête HTTP, le client et le serveur négocient une connexion sécurisée.
sequenceDiagram
participant C as Client
participant S as Serveur
C->>S: ClientHello<br/>(versions TLS supportées,<br/>cipher suites,<br/>clé publique éphémère)
S->>C: ServerHello + Certificat + Clé publique<br/>+ Finished
C->>C: Vérifie le certificat<br/>(chaîne, validité, nom)
C->>S: Finished<br/>(connexion établie)
Note over C,S: Données HTTP chiffrées circulent TLS 1.3 (2018) optimise tout :
- 1 RTT seulement (TLS 1.2 en demandait 2)
- Chiffres archaïques supprimés (RC4, 3DES, MD5…)
- 0-RTT possible pour les reconnexions
Le certificat X.509
Section intitulée « Le certificat X.509 »Un certificat est un fichier signé par une autorité de certification (CA). Il dit :
« Moi, Let’s Encrypt, je certifie que la clé publique ci-jointe appartient à
example.com, et c’est valable jusqu’au 15 janvier 2026. »
Champs principaux
Section intitulée « Champs principaux »Subject: CN=example.com, O=Example CorpIssuer: CN=R3, O=Let's EncryptValid from: 2025-10-15Valid until: 2026-01-15Serial number: 04:5A:6B:...Public Key: RSA 2048 bitsSignature: <signature de l'issuer>SAN: example.com, www.example.com, api.example.comSAN (Subject Alternative Names) liste tous les noms couverts par le certificat. C’est ainsi qu’un seul cert protège plusieurs sous-domaines.
Inspecter un certificat
Section intitulée « Inspecter un certificat »# Avec OpenSSLopenssl s_client -connect example.com:443 -servername example.com < /dev/null \ | openssl x509 -text -noout
# Plus simpleecho | openssl s_client -showcerts -connect example.com:443Dans le navigateur : clic sur le cadenas → Certificat.
La chaîne de certificats
Section intitulée « La chaîne de certificats »Un cert n’est pas signé directement par une racine de confiance. Il y a une chaîne :
flowchart TD
Root[Root CA<br/>ex. ISRG Root X1<br/>installée dans l'OS/navigateur]
Inter[Certificat intermédiaire<br/>ex. Let's Encrypt R3<br/>signé par la Root]
Leaf[Certificat du serveur<br/>example.com<br/>signé par l'intermédiaire]
Root --> Inter --> Leaf Le serveur doit envoyer la chaîne (sauf la racine, déjà connue du client). Une chaîne incomplète = warning navigateur.
Types de validation
Section intitulée « Types de validation »| Type | Validation | Coût | Cas |
|---|---|---|---|
| DV (Domain Validated) | « Tu contrôles le domaine » (challenge HTTP/DNS) | Gratuit (Let’s Encrypt) | 95 % des cas |
| OV (Organization Validated) | DV + vérification de l’organisation | ~100 €/an | Sites pro qui veulent montrer le nom |
| EV (Extended Validation) | OV + vérification approfondie | ~300 €/an | Banques (mais l’effet visuel a quasi disparu en 2020+) |
Pour 99 % des cas en 2026 : utilise Let’s Encrypt (DV, gratuit, automatisé).
Mettre en place HTTPS — 3 options
Section intitulée « Mettre en place HTTPS — 3 options »Option 1 — Caddy (le plus simple)
Section intitulée « Option 1 — Caddy (le plus simple) »Caddy obtient et renouvelle Let’s Encrypt automatiquement.
# Caddyfileexample.com { reverse_proxy localhost:3000}caddy runC’est tout. HTTPS, redirection HTTP→HTTPS, renouvellement, HTTP/3 — gratuit.
Option 2 — Nginx + Certbot
Section intitulée « Option 2 — Nginx + Certbot »# Installer Certbotsudo apt install certbot python3-certbot-nginx
# Obtenir un certificatsudo certbot --nginx -d example.com -d www.example.comCertbot modifie ta config Nginx automatiquement et installe un cron de renouvellement.
Option 3 — PaaS (Vercel, Netlify, Render…)
Section intitulée « Option 3 — PaaS (Vercel, Netlify, Render…) »HTTPS automatique, rien à configurer. Tu pousses ton code, le service gère cert + renouvellement.
Configurer HTTPS proprement
Section intitulée « Configurer HTTPS proprement »Forcer la redirection HTTP → HTTPS
Section intitulée « Forcer la redirection HTTP → HTTPS »# Nginxserver { listen 80; server_name example.com; return 301 https://$host$request_uri;}HSTS — HTTP Strict Transport Security
Section intitulée « HSTS — HTTP Strict Transport Security »Annonce au navigateur : « Pour ce domaine, n’utilise QUE HTTPS pendant N secondes, même si l’utilisateur tape http:// ».
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload| Directive | Effet |
|---|---|
max-age=31536000 | 1 an |
includeSubDomains | Applique aux sous-domaines |
preload | Hardcoded dans Chrome/Firefox/etc. (soumets sur hstspreload.org) |
Mixed content
Section intitulée « Mixed content »Une page HTTPS qui charge des ressources HTTP (images, scripts) :
<!-- ❌ MAUVAIS : mixed content --><img src="http://cdn.example.com/logo.png">
<!-- ✅ BON --><img src="https://cdn.example.com/logo.png"><!-- ou URL relative au protocole (vieux) --><img src="//cdn.example.com/logo.png">Le navigateur bloque les scripts/iframes mixed content (active mixed content), affiche un warning pour les images (passive mixed content).
Header pour tout migrer d’un coup :
Content-Security-Policy: upgrade-insecure-requestsRéécrit automatiquement les http: en https: dans la page.
Limites et pièges
Section intitulée « Limites et pièges »Ce que TLS ne protège pas
Section intitulée « Ce que TLS ne protège pas »- Le nom du domaine (visible via SNI dans le ClientHello — voir ECH/Encrypted ClientHello en cours d’adoption).
- Les métadonnées : taille des paquets, timing.
- La machine compromise : un keylogger sur le client voit tout.
Le bouton « j’accepte le certificat invalide »
Section intitulée « Le bouton « j’accepte le certificat invalide » »Toujours rouge. Même en dev. Si tu travailles en HTTPS local, utilise mkcert :
brew install mkcert # ou choco install mkcertmkcert -installmkcert localhost 127.0.0.1# génère localhost.pem + localhost-key.pemTon navigateur fait confiance, pas de warning.
Auto-évaluation
Section intitulée « Auto-évaluation »Pour aller plus loin
Section intitulée « Pour aller plus loin »- Bulletproof SSL/TLS and PKI — Ivan Ristić (la bible)
- SSL Labs Server Test — ssllabs.com/ssltest — note ta config
- Let’s Encrypt — Getting Started : letsencrypt.org/getting-started
- Mozilla SSL Configuration Generator — ssl-config.mozilla.org — génère une config Nginx/Apache/etc. solide
Suite : 2.4 — Anatomie d’un navigateur — comment le HTML reçu devient des pixels.