Plateforme de Cryptographie Par Kaci AMAOUCHE

Travaux Pratiques - Mise en œuvre de TLS et d'applications sécurisées

Appliquez les principes de sécurité cryptographique à des contextes réels


TP 1: Configuration et analyse d'un serveur TLS

Objectifs
  • Configurer un serveur web avec des paramètres TLS modernes et sécurisés
  • Analyser et évaluer la qualité d'une configuration TLS
  • Comprendre les vulnérabilités TLS communes et comment les atténuer

Partie 1: Configuration d'un serveur HTTPS avec Nginx

Dans cette partie, vous allez configurer un serveur web Nginx avec TLS en suivant les meilleures pratiques de sécurité.

  1. Génération des certificats

    Commencez par générer une autorité de certification locale et un certificat pour votre serveur :

    #!/bin/bash
    # Créer un répertoire pour les certificats
    mkdir -p ~/tls-lab/certs
    cd ~/tls-lab/certs
    
    # 1. Générer une clé privée et un certificat auto-signé pour la CA
    openssl genrsa -out ca.key 4096
    openssl req -x509 -new -nodes -key ca.key -sha256 -days 365 -out ca.crt \
        -subj "/C=FR/ST=Ile-de-France/L=Paris/O=ESGI-CA/OU=Crypto/CN=ESGI Certificate Authority"
    
    # 2. Générer une clé privée pour le serveur
    openssl genrsa -out server.key 2048
    
    # 3. Créer une demande de signature de certificat (CSR)
    openssl req -new -key server.key -out server.csr \
        -subj "/C=FR/ST=Ile-de-France/L=Paris/O=ESGI-Server/OU=Crypto/CN=localhost"
    
    # 4. Créer un fichier de configuration pour les extensions X509v3
    cat > server_ext.cnf << EOL
    [ v3_req ]
    basicConstraints = CA:FALSE
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    subjectAltName = @alt_names
    
    [alt_names]
    DNS.1 = localhost
    IP.1 = 127.0.0.1
    EOL
    
    # 5. Signer la CSR avec la CA pour obtenir le certificat
    openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
        -out server.crt -days 365 -sha256 -extfile server_ext.cnf -extensions v3_req
    
    # 6. Vérifier le certificat
    openssl x509 -in server.crt -text -noout
    
    echo "Certificats générés avec succès!"
  2. Configuration de Nginx avec TLS sécurisé

    Créez ou modifiez le fichier de configuration Nginx pour utiliser les certificats générés et appliquer les meilleures pratiques de sécurité TLS :

    # /etc/nginx/sites-available/secure-site.conf
    server {
        listen 80;
        server_name localhost;
        
        # Redirection de HTTP vers HTTPS (obligatoire pour la sécurité)
        location / {
            return 301 https://$host$request_uri;
        }
    }
    
    server {
        listen 443 ssl http2;  # Activation de HTTP/2 pour de meilleures performances
        server_name localhost;
        
        # Certificats TLS
        ssl_certificate     /chemin/vers/tls-lab/certs/server.crt;
        ssl_certificate_key /chemin/vers/tls-lab/certs/server.key;
        ssl_trusted_certificate /chemin/vers/tls-lab/certs/ca.crt;
        
        # Optimisation de la sécurité TLS
        
        # 1. Utiliser uniquement TLS 1.2 et TLS 1.3 (versions sécurisées)
        ssl_protocols TLSv1.2 TLSv1.3;
        
        # 2. Configurer des suites cryptographiques modernes et sécurisées
        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:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
        ssl_prefer_server_ciphers on;
        
        # 3. Activer le HSTS (HTTP Strict Transport Security)
        add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
        
        # 4. Paramètres Diffie-Hellman et sécurité supplémentaire
        ssl_dhparam /chemin/vers/tls-lab/certs/dhparam.pem;  # À générer séparément
        ssl_ecdh_curve secp384r1;  # Courbe elliptique sécurisée
        
        # 5. Optimisation des sessions SSL
        ssl_session_timeout 1d;
        ssl_session_cache shared:SSL:50m;
        ssl_session_tickets off;
        
        # 6. OCSP Stapling (pour une vérification plus efficace des certificats)
        ssl_stapling on;
        ssl_stapling_verify on;
        resolver 8.8.8.8 8.8.4.4 valid=300s;
        resolver_timeout 5s;
        
        # 7. Sécurité supplémentaire via des en-têtes HTTP
        add_header X-Frame-Options DENY;
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
        add_header Content-Security-Policy "default-src 'self'; script-src 'self'; img-src 'self'; style-src 'self'; font-src 'self'; connect-src 'self'; frame-src 'none'; object-src 'none'";
        
        # Configuration de base du serveur web
        root /var/www/html;
        index index.html;
        
        location / {
            try_files $uri $uri/ =404;
        }
    }

    Pour générer un paramètre Diffie-Hellman solide (requis par la configuration) :

    # Cette opération peut prendre plusieurs minutes
    openssl dhparam -out ~/tls-lab/certs/dhparam.pem 4096
  3. Test et déploiement de la configuration

    Testez votre configuration et déployez-la :

    # Vérifier la syntaxe de la configuration
    sudo nginx -t
    
    # Déployer la configuration (sous Ubuntu/Debian)
    sudo ln -s /etc/nginx/sites-available/secure-site.conf /etc/nginx/sites-enabled/
    sudo systemctl restart nginx
    
    # Vérifier que Nginx est en cours d'exécution
    sudo systemctl status nginx

Partie 2: Analyse et évaluation de la sécurité TLS

Utilisez des outils spécialisés pour évaluer la qualité de votre configuration TLS et identifier d'éventuelles vulnérabilités.

  1. Utilisation de testssl.sh

    testssl.sh est un outil en ligne de commande qui permet d'analyser en profondeur la configuration TLS d'un serveur :

    # Installation de testssl.sh
    git clone --depth 1 https://github.com/drwetter/testssl.sh.git
    cd testssl.sh
    
    # Analyse complète du serveur local
    ./testssl.sh --protocols --server-defaults --server-preference --headers --vulnerable --each-cipher https://localhost

    Analysez les résultats et identifiez :

    • Les protocoles supportés (seuls TLS 1.2 et 1.3 devraient être activés)
    • Les suites cryptographiques disponibles et leur ordre de préférence
    • Les éventuelles vulnérabilités connues (BEAST, FREAK, Heartbleed, etc.)
    • La qualité des paramètres Diffie-Hellman et des courbes elliptiques
    • La présence et la configuration correcte des en-têtes de sécurité HTTP
  2. Analyse d'un serveur public avec SSL Labs

    Si votre serveur est accessible publiquement, utilisez l'outil en ligne SSL Labs pour une analyse complète :

    Visitez SSL Labs Server Test et entrez l'URL de votre serveur.

    L'objectif est d'obtenir une note A+ pour votre configuration. Analysez les différentes sections du rapport :

    • Certificate : Validité, chaîne de confiance, algorithmes, etc.
    • Protocol Support : Versions de TLS supportées
    • Key Exchange : Qualité des paramètres d'échange de clés
    • Cipher Strength : Force des algorithmes de chiffrement
    • Protocol Details : Support de fonctionnalités comme OCSP, HSTS, etc.
    Interprétation des résultats

    Interprétez les résultats de l'analyse et répondez aux questions suivantes :

    1. Quelles sont les vulnérabilités potentielles détectées par ces outils ?
    2. Comment pourriez-vous améliorer votre configuration pour obtenir une meilleure note ?
    3. Quels compromis feriez-vous entre compatibilité des navigateurs et sécurité maximale ?
    4. Pourquoi la désactivation de TLS 1.0 et 1.1 est-elle recommandée, et quels problèmes cela pourrait-il poser ?

Partie 3: Implémentation d'un client TLS sécurisé

Dans cette partie, vous allez implémenter un client TLS en Python qui se connecte de manière sécurisée à un serveur HTTPS.

#!/usr/bin/env python3
# client_tls_securise.py
import ssl
import socket
import certifi
import urllib.parse

def client_tls_securise(url, verify=True, protocoles=None, ciphers=None):
    """
    Établit une connexion TLS sécurisée vers une URL HTTPS.
    
    Args:
        url (str): URL complète à laquelle se connecter (ex: https://example.com/path)
        verify (bool): Si True, vérifie le certificat du serveur
        protocoles (list): Liste des protocoles TLS à utiliser (None = par défaut)
        ciphers (str): Suites cryptographiques à utiliser (None = par défaut)
    
    Returns:
        tuple: (code de réponse HTTP, en-têtes, contenu)
    """
    # Analyser l'URL
    parsed_url = urllib.parse.urlparse(url)
    hostname = parsed_url.netloc
    port = parsed_url.port or 443  # Port HTTPS par défaut
    path = parsed_url.path or '/'
    
    # Créer un contexte SSL sécurisé
    context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile=certifi.where())
    
    # Configurer les options de sécurité
    if not verify:
        context.check_hostname = False
        context.verify_mode = ssl.CERT_NONE
        print("[AVERTISSEMENT] La vérification du certificat est désactivée!")
    
    # Configurer les protocoles TLS
    if protocoles:
        context.options = 0  # Réinitialiser les options
        if ssl.TLSVersion.TLSv1 not in protocoles:
            context.options |= ssl.OP_NO_TLSv1
        if ssl.TLSVersion.TLSv1_1 not in protocoles:
            context.options |= ssl.OP_NO_TLSv1_1
        if ssl.TLSVersion.TLSv1_2 not in protocoles:
            context.options |= ssl.OP_NO_TLSv1_2
        # Note: OP_NO_TLSv1_3 n'existe pas encore dans tous les environnements Python
    
    # Configurer les suites cryptographiques
    if ciphers:
        context.set_ciphers(ciphers)
    
    try:
        # Établir une connexion socket
        with socket.create_connection((hostname, port)) as sock:
            # Envelopper avec TLS
            with context.wrap_socket(sock, server_hostname=hostname) as ssock:
                print(f"Connexion établie avec {hostname}:{port}")
                print(f"Version TLS: {ssock.version()}")
                print(f"Suite cryptographique: {ssock.cipher()[0]}")
                print(f"Émetteur du certificat: {ssock.getpeercert()['issuer']}")
                
                # Envoyer une requête HTTP
                request = f"GET {path} HTTP/1.1\r\nHost: {hostname}\r\nConnection: close\r\n\r\n"
                ssock.sendall(request.encode())
                
                # Recevoir la réponse
                response = b""
                while True:
                    data = ssock.recv(4096)
                    if not data:
                        break
                    response += data
                
                # Analyser la réponse HTTP
                headers, _, body = response.partition(b'\r\n\r\n')
                status_line = headers.split(b'\r\n')[0].decode()
                status_code = int(status_line.split(' ')[1])
                
                return (status_code, headers.decode(), body.decode(errors='replace'))
    
    except ssl.SSLCertVerificationError as e:
        print(f"Erreur de vérification du certificat: {e}")
        return (None, None, str(e))
    except ssl.SSLError as e:
        print(f"Erreur SSL: {e}")
        return (None, None, str(e))
    except socket.error as e:
        print(f"Erreur de connexion: {e}")
        return (None, None, str(e))

# Exemple d'utilisation
if __name__ == "__main__":
    print("=== Client TLS Sécurisé ===")
    
    # 1. Connexion avec paramètres par défaut
    print("\n[Test 1] Connexion HTTPS standard à un site sécurisé")
    code, headers, body = client_tls_securise("https://www.ssllabs.com/")
    print(f"Code de réponse: {code}")
    print(f"Taille de la réponse: {len(body) if body else 0} caractères")
    
    # 2. Connexion avec TLS 1.2 uniquement
    print("\n[Test 2] Connexion restreinte à TLS 1.2 uniquement")
    code, headers, body = client_tls_securise(
        "https://www.ssllabs.com/",
        protocoles=[ssl.TLSVersion.TLSv1_2]
    )
    print(f"Code de réponse: {code}")
    
    # 3. Connexion avec suites cryptographiques spécifiques
    print("\n[Test 3] Connexion avec suites cryptographiques spécifiques")
    code, headers, body = client_tls_securise(
        "https://www.ssllabs.com/",
        ciphers="ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256"
    )
    print(f"Code de réponse: {code}")
    
    # 4. Connexion à un site auto-signé ou invalide (ex: serveur local)
    print("\n[Test 4] Connexion à un serveur avec certificat auto-signé (sans vérification)")
    code, headers, body = client_tls_securise(
        "https://localhost:443",
        verify=False
    )
    print(f"Code de réponse: {code}")
Exercices pratiques
  1. Exécutez le client TLS ci-dessus et analysez les résultats des différents tests.
  2. Identifiez les implications de sécurité lorsque verify=False est utilisé. Dans quelles circonstances une telle configuration pourrait-elle être justifiée ?
  3. Modifiez le code pour tester l'impact d'une limitation aux suites cryptographiques avec Perfect Forward Secrecy (PFS) uniquement.
  4. Testez votre client contre votre propre serveur Nginx configuré précédemment. Quels problèmes rencontrez-vous et comment les résoudre ?
  5. Comment pourriez-vous améliorer ce client pour implémenter le certificate pinning ?

TP 2: Attaque et défense des applications TLS

Objectifs
  • Comprendre les vulnérabilités des implémentations TLS et comment les exploiter
  • Apprendre à se défendre contre les attaques sur les protocoles cryptographiques
  • Implémenter des mécanismes de défense en profondeur dans les applications web

Partie 1: Analyse de cas d'attaques TLS

Dans cette partie, vous allez étudier des attaques réelles contre TLS et les mécanismes de mitigation associés.

Attaque Description Impact Mitigation
BEAST (2011) Attaque sur CBC dans TLS 1.0 qui permet de récupérer les cookies de session Récupération de données chiffrées (sessions, cookies)
  • Utiliser TLS 1.2+ uniquement
  • Utiliser des ciphersuites avec GCM (AEAD)
  • Implémenter l'empty fragment
CRIME / BREACH (2012-2013) Exploitation de la compression pour récupérer des données secrètes Fuite d'informations sensibles via le ratio de compression
  • Désactiver la compression TLS
  • Utiliser des CSRF tokens par requête
  • Éviter d'inclure des secrets dans le corps HTML
Heartbleed (2014) Fuite de mémoire dans l'extension Heartbeat d'OpenSSL Accès à la mémoire du serveur, incluant clés privées et données utilisateurs
  • Mettre à jour OpenSSL (>= 1.0.1g)
  • Révoquer et remplacer les certificats exposés
  • Forcer le renouvellement des sessions
POODLE (2014) Attaque sur le padding de SSLv3 permettant un déchiffrement Déchiffrement de données chiffrées via attaque oracle
  • Désactiver complètement SSLv3
  • Utiliser TLS_FALLBACK_SCSV
  • Implémenter l'HSTS
FREAK / Logjam (2015) Attaques forçant l'utilisation de clés d'export faibles Déchiffrement de trafic via MITM et calcul de clés
  • Désactiver toutes les suites cryptographiques d'export
  • Générer des paramètres DH d'au moins 2048 bits

Partie 2: Implémentation de la défense en profondeur pour une application web

Dans cette partie, vous allez développer une stratégie de défense complète pour une application web utilisant TLS.

Étude de cas

Vous êtes responsable de la sécurité d'une application web bancaire qui permet aux utilisateurs de consulter leurs comptes et d'effectuer des virements. L'application est construite avec :

  • Un backend en Python (Flask/Django) ou Node.js
  • Une base de données PostgreSQL
  • Un frontend en HTML/CSS/JavaScript (React ou Angular)
  • Une infrastructure hébergée sur AWS ou Azure

Votre mission est de concevoir et documenter une stratégie de sécurité complète qui va au-delà du simple TLS, en appliquant le principe de défense en profondeur.

Développez une solution qui couvre tous les aspects suivants :

  1. Configuration TLS optimale
    • Détaillez la configuration TLS complète (protocoles, ciphersuites, certificats)
    • Expliquez comment vous gérerez le renouvellement et la révocation des certificats
    • Définissez une stratégie pour la surveillance continue des vulnérabilités TLS
  2. En-têtes de sécurité HTTP
    • Configurez HSTS avec les paramètres appropriés
    • Implémentez une politique CSP (Content Security Policy) restrictive
    • Configurez les autres en-têtes de sécurité (X-Frame-Options, X-Content-Type-Options, etc.)
    • Justifiez chaque choix et paramètre
  3. Authentification multifacteur
    • Concevez un système d'authentification à deux facteurs (2FA)
    • Détaillez comment vous stockerez les informations d'identification de manière sécurisée
    • Expliquez comment vous gérerez les sessions et les jetons
  4. Protection contre les attaques web classiques
    • Implémentez des protections contre les injections SQL
    • Protégez l'application contre les attaques XSS et CSRF
    • Mettez en place des mécanismes de limitation de débit (rate limiting)
  5. Sécurité de l'API
    • Concevez un système d'autorisation robuste basé sur les rôles ou les attributs
    • Implémentez OAuth 2.0 ou OpenID Connect pour les API externes
    • Définissez une stratégie de gestion des jetons d'API
  6. Surveillance et réponse aux incidents
    • Mettez en place un système de journalisation sécurisé
    • Configurez des alertes pour les comportements suspects
    • Élaborez un plan de réponse aux incidents de sécurité

Évaluation - Sécurité TLS et applications chiffrées

Quiz (20 points)

Répondez aux questions suivantes en justifiant vos réponses de manière précise et concise.

  1. Pourquoi TLS 1.3 est-il considéré comme plus sécurisé que TLS 1.2 ? (2 points)

    • Citez au moins trois améliorations de sécurité spécifiques
    • Expliquez en quoi ces améliorations répondent à des vulnérabilités connues
  2. Expliquez le principe de "Perfect Forward Secrecy" et son importance dans TLS. (2 points)

    • Définissez le concept
    • Expliquez comment il est implémenté dans TLS
    • Analysez ce qui se passerait en son absence
  3. Décrivez le fonctionnement de la technologie HSTS et pourquoi elle est essentielle. (2 points)

    • Expliquez le format et les paramètres de l'en-tête
    • Détaillez comment il protège contre les attaques MITM
  4. Comparez les algorithmes de chiffrement AES-CBC et AES-GCM dans le contexte de TLS. (2 points)

    • Différences fondamentales entre ces modes
    • Avantages et inconvénients de chacun
    • Vulnérabilités spécifiques
  5. Quelles sont les étapes cryptographiques précises qui se déroulent lors d'une poignée de main (handshake) TLS 1.2 complète ? (3 points)

    • Détaillez chaque message et son rôle
    • Expliquez les échanges cryptographiques
    • Identifiez les informations protégées à chaque étape
  6. Comment fonctionne le mécanisme OCSP Stapling et pourquoi est-il préférable à l'OCSP standard ? (2 points)

  7. Analysez les risques de sécurité liés à l'utilisation du 0-RTT (Zero Round Trip Time) dans TLS 1.3. (2 points)

  8. Expliquez comment un attaquant pourrait exploiter une vulnérabilité de type "oracle de padding" contre TLS et comment s'en protéger. (3 points)

  9. Comment le Certificate Transparency (CT) contribue-t-il à renforcer la sécurité de l'écosystème TLS ? (2 points)