Mathis Garnier, DSI de la société fictive Ostrevia Logistique, a écrit son propre outil de chiffrement RSA pour envoyer une note confidentielle à trois agences. Pour « accélérer les calculs sur les vieux terminaux », il a choisi l'exposant public e = 3, et il chiffre le message tel quel, sans aucun remplissage.
Au cours d'un test d'intrusion autorisé, vous avez récupéré sur le relais de messagerie interne les trois envois de cette note, ainsi que les trois clés publiques de l'annuaire. Ces quatre fichiers sont à télécharger dans le bloc « Pièces jointes », sous l'énoncé.
Voici un extrait de l'outil, trouvé sur un partage réseau de la DSI :
# chiffrer_note.py (extrait)
E = 3 # « petit exposant = chiffrement plus rapide »
def chiffrer(message: str, n: int) -> int:
m = int.from_bytes(message.encode("utf-8"), "big")
return pow(m, E, n) # RSA brut : c = m^e mod n, sans remplissage
for agence in ("lyon", "nantes", "lille"):
n = lire_module(f"agence-{agence}.pem")
envoyer(agence, chiffrer(NOTE_AUDIT, n))Retrouvez le texte de la note : il contient le flag au format CSA{...}.
Rappel : RSA en bref
La clé publique est le couple (n, e). Pour chiffrer, on convertit le message en entier m, puis on calcule c = m^e mod n. Sans la clé privée, la seule méthode générale connue pour inverser l'opération consiste à factoriser n (ici 2048 bits), ce qui est hors de portée. Une mauvaise utilisation peut toutefois ouvrir des raccourcis.
Pourquoi un exposant de 3 sans remplissage est dangereux
Si le message est court, m³ reste plus petit que n : la réduction modulo n n'a jamais lieu et c = m³ exactement. Une simple racine cubique entière de c redonne alors m, sans aucune clé privée.
Ici, la note est plus longue : m³ dépasse n, et la racine cubique d'un seul chiffré ne donne rien de lisible. En revanche, le même message a été chiffré trois fois, avec le même exposant et trois modules différents. À vous de trouver comment en tirer parti.
Outils conseillés
OpenSSL pour lire les clés publiques, et Python 3, dont les entiers ne sont pas limités en taille :
openssl rsa -pubin -in agence-lyon.pem -noout -text
Leçon de sécurité
Ce challenge illustre une faute de mise en œuvre, pas une faiblesse de RSA : un même message chiffré sans remplissage, avec un petit exposant e, pour au moins e destinataires, peut être retrouvé sans aucune clé privée.
Jamais de RSA « brut ». Chiffrez toujours avec un remplissage aléatoire normalisé, RSAES-OAEP (PKCS#1 v2.2) : deux chiffrements du même message donnent alors des chiffrés sans rapport entre eux, et cette attaque devient impossible.
Exposant 65 537 et clés de taille suffisante. Pour le chiffrement, l'ANSSI recommande un exposant public strictement supérieur à 2^16 (65 537 est la valeur usuelle) et un module d'au moins 2048 bits, 3072 bits pour une protection au-delà de 2030.
Chiffrement hybride. En pratique, le document est chiffré par un algorithme symétrique (AES-GCM par exemple) avec une clé aléatoire, et RSA-OAEP ne sert qu'à chiffrer cette clé pour chaque destinataire.
Pas de cryptographie maison. Utilisez des formats et bibliothèques éprouvés (OpenPGP, S/MIME, libsodium, le module cryptography de Python) et faites relire tout code qui appelle directement pow(m, e, n).