Périmètre

Épreuve cryptographie du FCSC 2026 (ANSSI), challenge en ligne dans un cadre explicitement autorisé. Reproduction à fins pédagogiques.

Le challenge présente un chiffrement AES en mode CBC, un algorithme solide, mais toute la sécurité dépend du secret de la clé. Or la clé est entièrement déterminée par le code fourni.

Objectif

Reconstituer la clé à partir du générateur, puis déchiffrer le bloc de chiffré pour récupérer le flag.

1 · Le chiffrement

Côté challenge
key    = bytes([i for i in range(60, 76)])
cipher = AES.new(key, AES.MODE_CBC, iv=b"\\x00" * 16)
print(cipher.encrypt(FLAG).hex())
1417c97254a837b486e829faab5628df

Deux faiblesses cumulées : la clé est la suite d'octets 0x3C..0x4B (16 octets, donc AES-128), publiée en clair dans la logique du programme ; l'IV est nul et constant. Rien n'est secret.

2 · Déchiffrement

On reconstruit la même clé et le même IV, et on déchiffre le bloc unique.

Récupération du flag
key    = bytes(range(60, 76))
cipher = AES.new(key, AES.MODE_CBC, iv=b"\\x00" * 16)
print(cipher.decrypt(bytes.fromhex("1417c97254a837b486e829faab5628df")))
[+] FCSC{…}

Le chiffré ne fait qu'un bloc de 16 octets : le flag tient exactement dans un bloc AES, d'où l'absence de padding visible.

Côté défense
  • La robustesse d'AES ne vaut rien si la clé est dérivable du code ou de constantes prévisibles.
  • Une clé doit venir d'un secret aléatoire (CSPRNG) ou d'un KDF sur un mot de passe, jamais d'une suite déterministe.
  • Un IV doit être aléatoire et unique par message ; un IV nul constant fuit l'égalité des premiers blocs entre chiffrés.