Plateforme de Cryptographie Par Kaci AMAOUCHE

Chapitre 2: Chiffrement symétrique et asymétrique

Comprendre les différentes approches de chiffrement

Chapitre 2/5 Durée estimée: 3h

Introduction aux systèmes de chiffrement

Les systèmes de chiffrement sont au cœur de la cryptographie moderne. Ils transforment des données lisibles (texte clair) en données incompréhensibles (texte chiffré) à l'aide d'algorithmes mathématiques et de clés cryptographiques. Ces systèmes se divisent en deux grandes catégories: le chiffrement symétrique (à clé secrète) et le chiffrement asymétrique (à clé publique), chacun résolvant différents aspects du problème fondamental de la communication sécurisée.

Terminologie essentielle

  • Algorithme de chiffrement : Procédure mathématique qui transforme un texte clair en texte chiffré
  • Clé : Paramètre secret qui, combiné à l'algorithme, permet le chiffrement et le déchiffrement
  • Espace de clés : Ensemble de toutes les clés possibles pour un algorithme donné
  • Robustesse cryptographique : Résistance d'un système aux attaques, souvent liée à la taille de la clé
  • Chiffrement par bloc : Traite les données par blocs de taille fixe (ex: AES)
  • Chiffrement par flux : Traite les données bit par bit ou octet par octet (ex: RC4, ChaCha20)

Le principe de Kerckhoffs (1883) stipule que la sécurité d'un système cryptographique ne doit pas dépendre du secret de l'algorithme, mais uniquement du secret de la clé. Cette approche, fondamentale en cryptographie moderne, permet l'examen public des algorithmes tout en maintenant la sécurité par le secret des clés.

2.1. Chiffrement symétrique

Le chiffrement symétrique, également appelé chiffrement à clé secrète, utilise une clé unique et identique pour les opérations de chiffrement et de déchiffrement. Cette approche, qui constitue la forme la plus ancienne et la plus intuitive de cryptographie, est généralement rapide et efficace pour le traitement de grandes quantités de données.

Mathématiquement, si nous désignons par E l'algorithme de chiffrement, D l'algorithme de déchiffrement, K la clé secrète, M le message clair et C le message chiffré, le chiffrement symétrique est défini par :

$$C = E(K, M)$$

$$M = D(K, C)$$

Les propriétés essentielles d'un bon algorithme de chiffrement symétrique incluent :

  • Diffusion : Un changement minime dans le texte clair (ou la clé) doit produire un changement significatif dans le texte chiffré
  • Confusion : La relation entre la clé et le texte chiffré doit être aussi complexe que possible
  • Absence de biais statistiques : Le texte chiffré ne doit révéler aucune information sur le texte clair ou la clé
Émetteur Texte clair Chiffrement Clé secrète Récepteur Texte chiffré

Algorithmes de chiffrement symétrique

DES (Data Encryption Standard)

Développé dans les années 1970, DES a été le standard de chiffrement symétrique jusqu'aux années 2000. Il utilise une clé de 56 bits et opère sur des blocs de 64 bits. En raison de sa clé relativement courte, il est maintenant considéré comme non sécurisé.

Triple DES (3DES)

Extension de DES qui applique l'algorithme trois fois avec des clés différentes pour augmenter la sécurité. Sa formule est :

$$C = E_{K3}(D_{K2}(E_{K1}(P)))$$

Où \(E\) est l'opération de chiffrement, \(D\) est l'opération de déchiffrement, \(K1\), \(K2\) et \(K3\) sont trois clés différentes, et \(P\) est le texte en clair.

AES (Advanced Encryption Standard)

Adopté en 2001 comme successeur de DES, AES est actuellement le standard de chiffrement symétrique. Il supporte des tailles de clé de 128, 192 et 256 bits, et opère sur des blocs de 128 bits.

AES organise les données dans une matrice 4x4 appelée "state" et applique plusieurs tours de substitution (SubBytes), permutation (ShiftRows), mélange (MixColumns) et addition de clé (AddRoundKey).

Exemple de chiffrement AES-128

Pour AES-128, le processus comprend 10 tours avec la structure suivante :

  1. AddRoundKey (clé initiale)
  2. 9 tours de: SubBytes → ShiftRows → MixColumns → AddRoundKey
  3. Tour final: SubBytes → ShiftRows → AddRoundKey

La génération des sous-clés pour chaque tour est effectuée par un algorithme d'expansion de clé.

Autres algorithmes symétriques notables
  • Blowfish : Développé par Bruce Schneier, utilise des clés de longueur variable jusqu'à 448 bits
  • Twofish : Successeur de Blowfish, finaliste du concours AES
  • Serpent : Finaliste du concours AES, conçu pour être plus sécurisé qu'AES mais plus lent
  • ChaCha20 : Algorithme de chiffrement par flux moderne, utilisé dans TLS 1.3

Modes d'opération pour le chiffrement par blocs

Les algorithmes comme AES ou DES sont des chiffrements par blocs, qui opèrent sur des blocs de taille fixe. Pour chiffrer des messages de longueur arbitraire, on utilise différents modes d'opération :

Mode Description Avantages/Inconvénients
ECB (Electronic Codebook) Chaque bloc est chiffré indépendamment Simple mais non sécurisé pour les données structurées
CBC (Cipher Block Chaining) Chaque bloc est XORé avec le bloc chiffré précédent Sécurisé mais non parallélisable
CTR (Counter) Transforme le chiffrement par bloc en chiffrement par flux Parallélisable et sécurisé
GCM (Galois/Counter Mode) Mode CTR avec authentification Très utilisé pour les données authentifiées (HTTPS)

2.2. Chiffrement asymétrique

Le chiffrement asymétrique utilise une paire de clés: une clé publique pour le chiffrement et une clé privée pour le déchiffrement. Cette approche résout le problème de l'échange de clés du chiffrement symétrique.

Émetteur Texte clair Chiffrement Clé publique du récepteur Récepteur Texte chiffré Clé privée du récepteur

Algorithmes de chiffrement asymétrique

RSA (Rivest-Shamir-Adleman)

Développé en 1977, RSA est l'un des premiers et des plus utilisés algorithmes à clé publique. Sa sécurité repose sur la difficulté de factoriser le produit de deux grands nombres premiers.

Les étapes principales de RSA sont :

  1. Génération de clés :
    • Choisir deux grands nombres premiers distincts \(p\) et \(q\)
    • Calculer \(n = p \times q\)
    • Calculer \(\phi(n) = (p-1) \times (q-1)\)
    • Choisir un entier \(e\) tel que \(1 < e < \phi(n)\) et \(gcd(e, \phi(n)) = 1\)
    • Calculer \(d\) tel que \(d \times e \equiv 1 \pmod{\phi(n)}\)
    • La clé publique est \((n, e)\) et la clé privée est \((n, d)\)
  2. Chiffrement : Pour un message \(m\), le texte chiffré \(c\) est calculé par :

    $$c = m^e \bmod n$$

  3. Déchiffrement : Le message original est récupéré par :

    $$m = c^d \bmod n$$

Exemple simple de RSA

Avec de petits nombres pour illustration :

  • Choisir \(p = 3\) et \(q = 11\)
  • \(n = 3 \times 11 = 33\)
  • \(\phi(n) = (3-1) \times (11-1) = 2 \times 10 = 20\)
  • Choisir \(e = 7\) (premier avec 20)
  • Calculer \(d = 3\) (car \(7 \times 3 = 21 \equiv 1 \pmod{20}\))
  • Clé publique: (33, 7), Clé privée: (33, 3)

Pour chiffrer le message \(m = 2\) :

\(c = 2^7 \bmod 33 = 128 \bmod 33 = 29\)

Pour déchiffrer : \(m = 29^3 \bmod 33 = 24389 \bmod 33 = 2\)

Note: En pratique, RSA utilise des nombres premiers de plusieurs centaines de chiffres.

Diffie-Hellman

Bien que non utilisé directement pour le chiffrement, l'algorithme Diffie-Hellman est fondamental en cryptographie moderne car il permet à deux parties d'établir une clé secrète partagée sur un canal non sécurisé. Publié en 1976 par Whitfield Diffie et Martin Hellman, il représente la première solution pratique au problème de l'échange de clés.

Le protocole repose sur la difficulté calculatoire du problème du logarithme discret dans un corps fini. Son fonctionnement peut être résumé comme suit :

  1. Paramètres publics : Les participants s'accordent sur un grand nombre premier \(p\) et un générateur \(g\) (avec \(1 < g < p\)).
  2. Génération de secrets : Alice choisit un nombre secret \(a\) et calcule \(A = g^a \mod p\). Bob choisit un nombre secret \(b\) et calcule \(B = g^b \mod p\).
  3. Échange public : Alice envoie \(A\) à Bob, et Bob envoie \(B\) à Alice sur un canal qui peut être observé.
  4. Calcul de la clé partagée : Alice calcule \(K = B^a \mod p\) et Bob calcule \(K = A^b \mod p\). Ces deux valeurs sont identiques et égales à \(g^{ab} \mod p\), formant ainsi une clé secrète commune.
Exemple simplifié de Diffie-Hellman

Paramètres publics : \(p = 23\) et \(g = 5\)

  • Alice choisit \(a = 6\) et calcule \(A = 5^6 \mod 23 = 8\)
  • Bob choisit \(b = 15\) et calcule \(B = 5^{15} \mod 23 = 19\)
  • Alice envoie 8 à Bob, Bob envoie 19 à Alice
  • Alice calcule \(K = 19^6 \mod 23 = 2\)
  • Bob calcule \(K = 8^{15} \mod 23 = 2\)

La clé partagée est 2, qu'un attaquant ne peut pas calculer sans résoudre le logarithme discret.

Des variantes modernes comme ECDH (Elliptic Curve Diffie-Hellman) utilisent les courbes elliptiques pour offrir la même sécurité avec des clés beaucoup plus courtes. Diffie-Hellman est souvent utilisé avec des algorithmes symétriques pour créer des systèmes hybrides efficaces et sécurisés, comme dans le protocole TLS qui sécurise les communications web.

ElGamal

Proposé par Taher ElGamal en 1985, ce système cryptographique est basé, comme Diffie-Hellman, sur le problème du logarithme discret. ElGamal présente la particularité d'être utilisable à la fois pour le chiffrement asymétrique et pour la signature numérique, ce qui en fait un système cryptographique complet.

Le chiffrement ElGamal fonctionne comme suit :

  1. Génération de clés :
    • Choisir un grand nombre premier \(p\) et un générateur \(g\) (comme dans Diffie-Hellman)
    • Choisir un nombre aléatoire \(x\) (clé privée) et calculer \(y = g^x \mod p\) (clé publique)
    • La clé publique est le triplet \((p, g, y)\), la clé privée est \(x\)
  2. Chiffrement :
    • Pour chiffrer un message \(m\) (où \(0 < m < p\)), choisir un nombre aléatoire \(k\)
    • Calculer \(c_1 = g^k \mod p\)
    • Calculer \(c_2 = m \cdot y^k \mod p\)
    • Le texte chiffré est le couple \((c_1, c_2)\)
  3. Déchiffrement :
    • Calculer \(s = c_1^x \mod p\)
    • Calculer \(m = c_2 \cdot s^{-1} \mod p\)

La particularité d'ElGamal est que, pour un même message, chaque chiffrement produit un résultat différent en raison du nombre aléatoire \(k\). Cette propriété, appelée chiffrement probabiliste, empêche certaines attaques par analyse statistique mais augmente la taille du texte chiffré.

ECC (Elliptic Curve Cryptography)

La cryptographie sur les courbes elliptiques, proposée indépendamment par Neal Koblitz et Victor Miller en 1985, représente une évolution majeure dans les systèmes asymétriques. Plutôt que d'utiliser la structure multiplicative d'un corps fini comme RSA ou Diffie-Hellman, ECC utilise les propriétés algébriques des courbes elliptiques sur des corps finis.

Une courbe elliptique sur un corps fini est définie par une équation de la forme :

$$y^2 = x^3 + ax + b \quad \text{(mod } p\text{)}$$

où \(a\) et \(b\) sont des constantes et \(p\) est un nombre premier. Les points de la courbe, ainsi que le "point à l'infini", forment un groupe additif où l'opération principale est l'addition de points.

L'avantage principal d'ECC est son efficacité en termes de taille de clé. Une clé ECC de 256 bits offre approximativement le même niveau de sécurité qu'une clé RSA de 3072 bits. Cet avantage devient crucial dans les environnements à ressources limitées comme les smart cards, les IoT ou les applications mobiles.

Les principaux algorithmes basés sur ECC incluent :

  • ECDH (Elliptic Curve Diffie-Hellman) : Variante de Diffie-Hellman pour l'échange de clés
  • ECDSA (Elliptic Curve Digital Signature Algorithm) : Algorithme de signature numérique
  • ECIES (Elliptic Curve Integrated Encryption Scheme) : Système de chiffrement hybride
Note sur la sécurité d'ECC

Le choix des paramètres de courbe est crucial pour la sécurité d'ECC. Certaines courbes standardisées, notamment celles proposées par le NIST, ont suscité des inquiétudes concernant de potentielles "backdoors". En réponse, des courbes alternatives comme Curve25519 (développée par Daniel J. Bernstein) ont été créées avec des processus de génération transparents et des propriétés mathématiques offrant une meilleure résistance contre certaines classes d'attaques.

2.3. Comparaison et usage hybride

Critère Chiffrement symétrique Chiffrement asymétrique
Vitesse Rapide Lent (100-1000x plus lent)
Gestion des clés Complexe (distribution) Plus simple (pas besoin d'échange préalable)
Longueur de clé Courte (128-256 bits) Longue (2048-4096 bits pour RSA)
Cas d'utilisation Chiffrement de grandes quantités de données Échange de clés, signatures numériques

Systèmes hybrides

En pratique, la plupart des systèmes cryptographiques modernes utilisent une approche hybride :

  1. Une clé symétrique aléatoire (clé de session) est générée
  2. Les données sont chiffrées avec cette clé symétrique
  3. La clé symétrique est chiffrée avec la clé publique du destinataire
  4. Le message chiffré et la clé symétrique chiffrée sont envoyés ensemble

Cette approche combine la rapidité du chiffrement symétrique avec la facilité de gestion des clés du chiffrement asymétrique.

Applications pratiques

  • TLS/SSL : Protocoles de sécurité pour les communications sur Internet utilisant une approche hybride
  • PGP (Pretty Good Privacy) : Système de chiffrement pour emails et fichiers
  • Systèmes de paiement : Transactions en ligne sécurisées
  • VPN (Virtual Private Networks) : Communications sécurisées sur des réseaux non sécurisés

Exercices associés

Mettez en pratique les concepts de ce chapitre avec les exercices dédiés.

Accéder aux exercices

Exemple de code (Python)


# Exemple d'implémentation AES en Python
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import os

def encrypt_aes(message, key):
    # Générer un vecteur d'initialisation
    iv = os.urandom(16)
    
    # Créer le chiffreur
    cipher = Cipher(
        algorithms.AES(key),
        modes.CBC(iv),
        backend=default_backend()
    )
    encryptor = cipher.encryptor()
    
    # Paddez le message pour qu'il soit un multiple de 16
    padded_message = message + b' ' * (16 - len(message) % 16)
    
    # Chiffrer le message
    ciphertext = encryptor.update(padded_message) + encryptor.finalize()
    
    return iv + ciphertext  # Concaténer IV et texte chiffré

def decrypt_aes(ciphertext, key):
    # Extraire IV (16 premiers octets)
    iv = ciphertext[:16]
    ciphertext = ciphertext[16:]
    
    # Créer le déchiffreur
    cipher = Cipher(
        algorithms.AES(key),
        modes.CBC(iv),
        backend=default_backend()
    )
    decryptor = cipher.decryptor()
    
    # Déchiffrer le message
    plaintext = decryptor.update(ciphertext) + decryptor.finalize()
    
    # Enlever le padding
    return plaintext.rstrip()

# Générer une clé AES-256
key = os.urandom(32)  # 32 octets = 256 bits

# Tester
message = b"Message secret"
encrypted = encrypt_aes(message, key)
decrypted = decrypt_aes(encrypted, key)

print(f"Original: {message}")
print(f"Déchiffré: {decrypted}")