vendredi 26 février 2016

DISSIMULER UN MESSAGE SECRET DANS UNE IMAGE GRACE A LA STEGANOGRAPHIE


Bonjour, 

Aujourd’hui je vais vous montrer comment cacher un message dans une image par une méthode dite de stéganographie avec le langage PHP (Personal Home Page). 

Mais avant d’entrer vivement dans le sujet : 

Qu’est ce que la stéganographie ? 

La stéganographie est une méthode qui consiste à dissimuler un texte, une image, un son, une vidéo ou même encore un logiciel dans un objet (image, son, vidéo, …). Cette méthode peut vous aider à échanger avec votre correspondant via internet, des réseaux sociaux, des périphériques de stockage ou tout autre media des messages « secrets » qui passeront inaperçu pour les autres.

La technique que nous allons utiliser repose sur la méthode dite d’usage de bits de poids faible (Least Significant Bit, LSB) d’une image. Cette méthode consiste à modifier le bit de poids faible des pixels codant l’image. Une image numérique est une suite de pixels dont on code la couleur à l’aide d’un triplet d’octets, par exemple pour une couleur RGB (Red Green Blue) sur 24 bits, chaque octet indique en binaire l’intensité de la couleur correspondante : rouge, vert ou bleu. 

(PS : noté qu’un(1) octet correspond à huit (8) bits) 

On peut représenter une image dans un tableau ou une matrice, par exemple la matrice carrée 3 * 3 suivante représente une image numérique : 
Chaque entrée de cette matrice (ou tableau) représente un pixel couleur, chaque triplet de bits (0 ou 1) code la quantité de l’une des trois couleurs primaires du pixel. Le bit le plus à droite de chaque triplet est un bit de poids faible. Si par exemple on souhaite cacher le message 111 110 001 101 111 101 000 111 101, dans l’image représentée par la matrice précédente on obtiendra la nouvelle matrice suivante :

Le résultat obtenu est une image très peu différente de l’image d’origine, l’œil humain ne pourra pas faire la différence entre l’image d’origine de départ et l’image finale contenant le message dissimulé.  


Maintenant que vous savez ce que c’est que la stéganographie et le procédé utilisé pour dissimuler un message dans une image avec la méthode de bits de poids faible (LSB) nous allons à présent entrer dans le vif du sujet.



Comment dissimuler un message dans une image grâce à du code PHP ?



Nous allons procéder comme déjà indiqué plus haut avec la méthode LSB. Pour des besoins de test j’ai développé la petite application PHP (dont le code source est disponible ici) avec pour interface principale la page suivante :





L’application en question à deux principales fonctionnalités : dissimuler un message dans une image et afficher un message caché dans une image (si le message existe). 


Dissimuler un texte dans une image


NB : les images utilisées pour cette opération doivent être des images au format Bitmap (BMP), tout autre format (JPG, PNG, …) ne produira pas le résultat attendu et générera parfois des erreurs, ceci est due au fait que les autres formats d’images comme par exemple JPEG compresse l’image, cela signifie qu’on n’a plus l’équivalence « un octet correspond à la valeur de  la couleur d’un pixel », et par conséquent si on souhaite dissimuler un message dans une image avec un tel format le message deviendra illisible. 


La fonction PHP qui permet de cacher un message dans une image est la suivante : 

Les nombres suivants correspondent aux commentaires du code de la fonction PHP qui permet de dissimuler un message dans une image au format Bitmap :


1: je stocke dans la variable $message le texte que je souhaite dissimuler dans l’image, ici elle va contenir un texte envoyé depuis un formulaire par une méthode POST (je l’ai fait ainsi pour qu’il soit en accord avec mon application, vous pouvez modifier ce paramètre pour qu’il convient à vos exigences). Il faut également noter que le texte peut contenir autant de caractères que vous désirez ;


2: ici on stocke dans la variable $lien le chemin et le nom de l’image qu’on souhaite utiliser pour y dissimuler notre message « secret », je tiens à préciser une fois de plus que le format de l’image doit être Bitmap (bmp) ;

3: ici on ajoute à la variable contenant le message, le caractère défini à la 26 ième position du code ASCII, obtenu grâce à la fonction chr(). En regardant dans la table ASCII ci-dessous, on voit que cela correspond au caractère EOF (End Of File), donc un caractère non imprimable. Il ne va donc, en théorie, jamais apparaître dans notre message à dissimuler. Ce caractère va nous servir uniquement à indiquer la fin du message ; 

4: ici on ouvre le fichier image, l’option « r+b » permet d’ouvrir un fichier binaire en mode « lecture/écriture » ; 


5: on place notre curseur au niveau du 54 ième  pixel, pour sauter les informations contenues dans le « header » (l’entête) de notre image ;


6: la fonction ord() permet de retourner le code ASCII d’un caractère ;

7: on récupère les bits de poids faible sous forme binaire ;


8: On ajoute un zéro (0) devant le nombre binaire récupéré si nécessaire ;


9: On convertit la chaîne de caractères contenu dans la variable $octet_binaire en un tableau de longueur deux (2) ;


10: On récupère un seul octet, sous forme de caractère ;


11: On convertit l’octet récupéré en nombre grâce à sa valeur correspondante dans la table du code ASCII ;

12: On rend les bits de poids faible égaux à zéro ;

13: On reconvertit l’octet en base décimal (base 10) pour pouvoir faire une addition ;

14: la fonction fseek() renvoie une position donnée par rapport à la position actuelle, ensuite on écrase l'octet suivant, qu’on ne veut pas encore modifier;

15: On écrit dans le fichier image, en écrasant l'octet suivant ;

16: Enfin on ferme notre fichier image.

La fonction ci-dessus permet de dissimuler un texte dans une image au format Bitmap, nous pouvons tester cette fonction grâce à notre « petite » application PHP de Stéganographie :

Tout d’abord nous sélectionnons l’image dans laquelle nous souhaitons dissimuler un message « secret », pour ce faire nous cliquons sur le bouton « Parcourir »




Ensuite nous choisissons l’image où nous souhaitons dissimuler notre message « secret » ;
 


Une fois l’image choisie nous cliquons sur le bouton « cacher le message » : 



Saisissez le message que vous souhaitez dissimuler dans l’image choisie et cliquez sur le bouton « envoyer le message » ;



Une fois cela fait l’application vous retourne une notification vous indiquant que votre message a été parfaitement insérer dans votre image.



Si l’application retourne le message précédent alors notre nouvelle image (stocké dans le répertoire « www/steganographie/photos » de notre application) contient bel et bien un message « caché » à l’œil nu la différence avec l’image d’origine est impossible mais si on se sert d’un éditeur hexadécimal comme « Hex Editor » pour observer nos images (d’origine et finale) nous observerons que dans l’image finale presque tous les octets ont été modifiés. Les figures suivantes montrent la représentation hexadécimale de l’image d’origine et de l’image finale :



Image_d_origine
 

Image_finale


A présent vous savez dissimuler un message « secret » dans une image avec du code PHP. Maintenant qu’on sait dissimuler un texte dans une image nous pouvons voir comment récupérer et afficher un message caché dans une image au format Bitmap.


Afficher Un texte en clair dissimulé dans une image



C’est bien de savoir dissimuler un texte dans une image mais tout aussi important de savoir déchiffrer un texte qui serait caché dans une image, raison pour laquelle nous aborderons cette partie.  

(PS : Une fois de plus cette opération à lieu sur une image au format Bitmap (bmp).)

Le bout de code PHP qui permet de récupérer et d’afficher un message dissimulé dans une image est le suivant :
 

Les nombres suivants correspondent aux commentaires du code de la fonction PHP qui permet de récupérer et afficher un message dissimulé dans une image au format Bitmap :


1: nous créons une variable $lien qui contient le chemin et le nom du fichier image dont on souhaite récupérer (si il existe) le message caché ; ici il s’agit d’une donnée passé depuis une URL (Uniform Resource Locator), vous pouvez la modifier pour qu’elle réponde a vos exigences ;


2: on ouvre notre fichier image en mode « lecture » uniquement, pour cette opération (récupérer et afficher le message) il n’est pas nécessaire d’ouvrir le fichier en essayant de le modifier, d’où le mode « lecture » suffit ;


3: on saute le header;


4: on crée une boucle « while » qui consistera à effectuer un certain nombre d’opérations de manière répétitive tant que l’image ne sera pas entièrement lu jusqu’à sa dernière ;


5: on lit un caractère du fichier image ;


6: on retourne le code ASCII du caractère lu à l’instruction 5, vous vous souvenez ? c’est le rôle de la fonction ord() ;


7: on stocke dans la variable $bits_pf  le reste de la division de la valeur contenue dans la variable $octet_image par quatre (4), en d’autres termes on stocke la valeur du modulo ;


8: on récupère les bits de poids faible sous forme binaire ;


9: on ajoute un zéro (0) si nécessaire ;


10: on concatène les bits de poids faible trouvés  à la valeur initiale stocké dans la variable $tampon ;


11: nous effectuons une condition qui prendra effet si et seulement si la taille de la valeur contenu dans notre variable tampon est égal à huit (8) ;


12: nous convertissons en base décimale la valeur de notre variable tampon ;


13: nous affichons le message caché dans l’image ;


14: si l'on n'est pas arrivé à la fin du message, donc le caractère renvoyé par la fonction chr()est différent du caractère EOF (rappelez vous ce caractère nous permet de savoir si on a atteint la fin du message), on ajoute le caractère trouvé ;


15: et enfin on réinitialise le tampon.



La fonction ci-dessus permet de récupérer et d’afficher un texte dissimulé dans une image au format Bitmap, nous pouvons tester cette fonction grâce à notre « petite » application PHP de Stéganographie :

Tout d’abord comme précédemment pour cacher un message, nous sélectionnons en cliquons sur le bouton « Parcourir » l’image que nous souhaitons examiner et y afficher le contenu d’un éventuel message « secret » caché, une fois l’image choisie nous cliquons cette fois-ci sur le bouton « afficher le message » :



Une fois cela fait, vous devriez en principe avoir une page vous affichant le message caché déchiffré en clair et en couleur rouge, comme le montre l’image suivante :



A présent vous savez récupérer et afficher un texte dissimulé dans une image.


Comme petit récapitulatif : nous avons appris comment dissimuler un message dans une image, ensuite comment récupérer et afficher un texte en clair et de manière déchiffré  qui était au préalable dissimulé dans une image, nous tenons à préciser (une fois de plus) que ces deux opérations ne sont possibles que sur des images au format Bitmap (bmp), du fait que les autres formats tel que JPG, ou PNG compressent l’image et rendraient si c’est le cas un texte caché complètement illisible. En petit bonus je vous donne le code source en PHP de la « petite » application que j’ai codé et qui nous a servi pour tester nos différentes opérations (disponible une fois de plus ici).



Merci d’avoir suivi le tutoriel jusqu’à la fin.
 
A très bientôt !!!



11 commentaires :

  1. cool le tuto, bonne continuation !!!

    RépondreSupprimer
  2. Bonsoir, le lien pour le code source ne marche pas :/ possible d'en avoir un autre ?

    RépondreSupprimer
  3. Bonjour, Merci The135849 de m'avoir signalé le problème avec le lien de téléchargement du code source, je vous tiendrai informé une fois le problème résolu d'ici là les personnes désirant avoir le code peuvent me contacter par mail. Merci de votre compréhension

    RépondreSupprimer
    Réponses
    1. Bonsoir, je vous ai envoyer un mail dans l'espoir de recevoir le code, si jamais je me suis trompée de mail voici le mien sissi135849@gmail.com Merci beaucoup

      Supprimer
    2. Bonjour, The135849 je vous ai envoyé le code source à l'adresse que vous m'avez donné, j'espère que vous l'avez bien reçu si ce n'est pas le cas informez moi de nouveau je vous le renverrai avec plaisir.

      Supprimer
  4. Bonsoir, j'aurais besoin du code php en urgence mais il n'est pas dispo, merci de répondre au mail.

    RépondreSupprimer
    Réponses
    1. Bonjour, Rostom Rossoneri envoyez moi votre mail et je vous renverrai le code source d'ici peu le problème avec le lien du téléchargement sera résolu.Merci

      Supprimer
  5. Bonjour, juste pour vous informer que les liens de téléchargement sont de nouveau fonctionnels. Merci à tous pour vos participations et vos remarques je reste à votre disposition pour tout autre éventuel problème et renvoyez moi l'ascenseur en me tenant informé de toutes améliorations bénéfiques apporté au code source question que je le mette à jour sur le blog :).Merci de votre Aide

    RépondreSupprimer
  6. Bonjour, j'aurais besoin du code source
    merci d’avance

    RépondreSupprimer
    Réponses
    1. Bonjour MOHAMED en parcourant l'article vous trouverez des liens pour télécharger le code source, faites en bon usage et svp tenez moi informé de toutes améliorations que vous apporterez au code pour que je puisse le mettre à jour. Merci

      Supprimer
  7. j'ai besoin d'une explication de la technique DCT pour images compressées JPEG. merci

    RépondreSupprimer