Stéganographie

Cette activité est fortement inspirée du dossier paru sur le site bibmath.

Les images utilisées sont toutes issues du site Pixabay et libres de droits.

La stéganographie, du grec stegano (dissimuler), est une méthode de cryptographie qui consiste, plutôt que de crypter un message, à le cacher dans une image selon un procédé plus ou moins complexe.

On s'intéresse en particulier à la dissimulation d'une image dans une autre image.

Le principe

Considérons deux images en niveau de gris, au format pgm 8 bits. Chaque pixel est donc codé par un entier compris en 0 et 255. Nous supposons de plus ces deux images de même taille.

La première image image1.pgm est la suivante (dimensions : 640x426, cliquer sur l'image pour obtenir le fichier pgm) :

image50

La seconde image image2.pgm est la suivante (dimensions : 640x426, cliquer sur l'image pour obtenir le fichier pgm) :

image50

L'objectif est de cacher l'image 2 dans l'image 1. Comment faire ?

Chaque pixel de chacune des deux images est codé par un entier compris entre 0 et 255. Écrit en base 2, cet entier s'écrit avec 8 chiffres (en ajoutant éventuellement des zéros inutiles au début du nombre). Prenons par exemple un pixel de la première image codé par le nombre binaire 1011 0101 : les quatre premiers chiffres ont plus de poids dans la valeur de ce nombre que les quatre derniers puisqu'ils sont associés à de plus grandes puissances de 2. Nous les appellerons bits de poids lourds. Les quatre derniers sont donc des bits de poids faible.

Si on remplace ce nombre par un nombre dont on ne modifie que les quatre bits de poids faible (les quatre derniers), alors l'image sera assez peu modifiée. C'est cette remarque qui permet de cacher l'image 2 dans l'image 1. Il suffit de créer une nouvelle image dont chaque pixel est formé des bits de poids lourd de chacune des deux images de départ.

Pour chaque pixel des deux images :

Image 1 Image 2 Image cryptée
1011 0101 0110 1100 1011 0110

Comme on n'a modifié que les bits de poids faible de l'image 1, l'image cryptée ressemblera beaucoup à l'image 1, mais un programmeur averti saura en extraire l'image 2 ...

Voici, à gauche, l'image 1 et, à droite, l'image cryptée (la pauvre vache est perdue dans la ville !).

Image 1 Image cryptée
image image

Mini-projet

Mini-projet

Votre mission, si vous l'acceptez, consiste en deux choses :

  1. Programmer un algorithme permettant de créer l'image cryptée à partir des deux images de départ. Il s'agit de définir une fonction qui prend en arguments deux images de mêmes dimensions et qui retourne l'image cryptée.
  2. Programmer un algorithme permettant de retrouver l'image cachée dans une image cryptée. Il s'agit de définir une fonction qui prend en argument une image cryptée et qui retourne l'image cachée.

En cas de besoin, quelques indications :

Indications
  • La fonction bin() permet de convertir un entier en sa représentation binaire sous forme de chaîne de caractères. Cependant, le résultat ne contient pas les zéros inutiles en début de chaîne !!! Par exemple bin(45) retourne '0b101101'.
  • Pour accéder aux éléments d'une chaîne de caractères, on utilise les crochets comme pour les listes. Un indice négatif indique que l'on part de la fin de la chaîne. Par exemple, si mot = "indication", mot[2:-2] retourne "dicati".

Pour tester vos algorithmes

Pour tester votre programme, vous pouvez utiliser l'image cryptée présentée dans le tableau ci-dessus et essayer de recréer à partir de celle-ci l'image 2 (l'image cryptée au format pgm peut être téléchargée en cliquant sur l'image dans le tableau).

Voici une autre image à tester. Elle contient un message secret ...

image

Pour aller plus loin

L'article suivant, sur le site bibmath présente une généralisation de la méthode utilisée ici pour des images en couleurs.

L'ensemble du dossier peut être lu pour un complément culturel sur le sujet.

Défi !

Dans une image en couleur au format RGB, chaque pixel est codé par trois entiers compris entre 0 et 255.

On peut donc cacher dans une telle image trois images en niveaux de gris différentes : une dans chaque composante de couleur.

En suivant cette idée, j'ai caché trois messages dans l'image ci-dessous (en cliquant sur l'image, on peut la télécharger au format ppm). Saurez-vous les retrouver ?

image