La stéganographie : ne pas chiffrer, mais dissimuler
Chiffrer un message le rend illisible, mais cela se voit. La stéganographie fait autre chose : elle cache l'existence même du message, par exemple dans une photo. Cette partie, facultative, réutilise ce que tu as vu dans le thème Photographie numérique.
CoursLe dernier bit
Dans une image RVB, chaque couleur d'un pixel est un nombre de 0 à 255, c'est-à-dire un octet. Changer ce nombre de 1 ne se voit pas à l'œil : 200 et 201 donnent deux rouges quasi identiques. On peut donc utiliser le dernier bit de chaque nombre pour stocker un bit du message.
Le dernier bit, en Python
200 % 2 donne 0 (nombre pair) ; 201 % 2 donne 1 (nombre impair).
Le dernier bit d'un nombre est donc nombre % 2.
Dans ce bonus, on cache le message dans le canal rouge des pixels, en lisant l'image ligne par ligne. Le message est écrit en code ASCII, 8 bits par caractère. Le fichier image_secrete.png (dans l'archive à télécharger : Cryptage.zip) contient un message caché. On utilise un fichier PNG : un fichier JPEG modifierait les valeurs des pixels.
ExercicesExercices
EX 33Je découvre🌶️prise en main
Exercice 33 — Invisible ?
Quel est le dernier bit de 200, de 201, de 37, de 88 ? (utilise % 2)
Si le message est « A » (code ASCII 65, soit 01000001 en binaire), quels bits doit-on écrire dans 8 pixels successifs ?
Pourquoi la modification d'un bit sur un pixel est-elle invisible ?
Indice
65 en binaire : 64 + 1, soit 01000001.
📝 réponses dans ton compte rendu, exercice 33
EX 34Je programme🌶️🌶️application
Exercice 34 — Lire le message caché
Enregistre image_secrete.png dans le même dossier que ton programme, puis complète les deux lignes du programme (l'extraction du dernier bit, puis la conversion en caractère).
lire.py
from PIL import Image
img = Image.open("image_secrete.png").convert("RGB")
largeur, hauteur = img.size
bits = ""for y inrange(hauteur):
for x inrange(largeur):
r, v, b = img.getpixel((x, y))
bits = bits + str(r % ...) # à compléter : le dernier bit de r
message = ""for i inrange(0, len(bits) - 7, 8):
octet = bits[i:i + 8]
code = int(octet, 2)
if code == 0:
break
message = message + chr(...) # à compléterprint(message)
Complète, exécute : quel est le message caché ?
À quoi sert int(octet, 2) ?
Que signifie if code == 0: break ?
Indice
int("01000001", 2) donne 65, et chr(65) donne "A".
💾 NOM_Prenom_ex34.py
EX 35Je synthétise🌶️🌶️🌶️plusieurs étapes
Exercice 35 — Combien peut-on cacher ?
Une image fait 800 × 600 pixels. Combien de bits peut-on cacher avec un bit par pixel ?
Combien de caractères cela fait-il ?
Pourquoi la stéganographie ne remplace-t-elle pas le chiffrement ? Que faire pour combiner les deux ?