Stéganographie LSB

Il était une fois j'écrivais mon premier message sur le hub. Et ce billet était consacré à un problème très intéressant, à savoir la stéganographie. Bien entendu, la solution proposée dans ce vieux sujet ne peut pas être appelée stéganographie au vrai sens du terme. C'est juste un jeu avec des formats de fichiers, mais néanmoins un jeu assez intéressant.

Aujourd'hui, nous allons essayer de creuser un peu plus et d'examiner l'algorithme LSB. Si vous êtes intéressé, vous êtes les bienvenus sous chat. (Sous la coupe se trouve le trafic : environ un mégaoctet.)

Tout d’abord, il est nécessaire de faire une brève introduction. Tout le monde sait que le but de la cryptographie est de rendre impossible la lecture d’informations secrètes. Bien sûr, la cryptographie a ses applications, mais il existe une autre approche de la protection des données. Nous n’avons pas besoin de chiffrer les informations, mais faisons semblant de ne pas les avoir. C'est précisément pourquoi la stéganographie a été inventée. Wikipédia nous assure que « la stéganographie (du grec στεγανοσ - caché et du grec γραφω - j'écris, littéralement « écriture secrète ») est la science de la transmission cachée d'informations en gardant secret le fait même de la transmission.

Bien entendu, personne n’interdit de combiner les méthodes cryptographiques et stéganographiques. De plus, dans la pratique, ils le font, mais notre tâche est d'en comprendre les bases. Si vous étudiez attentivement l'article Wikipédia, vous découvrirez que les algorithmes de stéganographie incluent ce qu'on appelle. conteneur et message. Un conteneur est toute information qui permet de cacher notre message secret.

Dans notre cas, le conteneur sera une image au format BMP. Tout d'abord, regardons la structure de ce fichier. Le fichier peut être divisé en 4 parties : l'en-tête du fichier, l'en-tête de l'image, la palette et l'image elle-même. Pour nos besoins, nous avons seulement besoin de savoir ce qui est écrit dans l’en-tête.

Les deux premiers octets de l'en-tête sont la signature BM, puis la taille du fichier en octets est écrite dans un double mot, les 4 octets suivants sont réservés et doivent contenir des zéros, et enfin, un autre double mot contient le décalage depuis le début du fichier aux octets réels de l’image. Dans un fichier bmp 24 bits, chaque pixel est codé avec trois octets BGR.

Maintenant que nous savons comment accéder à l'image, il ne reste plus qu'à comprendre comment y écrire les informations dont nous avons besoin. Pour cela nous aurons besoin de la méthode LSB. L'essence de la méthode est la suivante : nous remplaçons les bits les moins significatifs dans les octets responsables du codage des couleurs. Disons que si l'octet suivant de notre message secret est 11001011 et que les octets de l'image sont...11101100 01001110 01111100 0101100111..., alors l'encodage ressemblera à ceci. Nous allons diviser l'octet du message secret en 4 parties de deux bits : 11, 00, 10, 11, et remplacer les bits de poids faible de l'image par les fragments résultants : ...11101111 0100110+0 (011111)XNUMX XNUMX10 0101100111…. Un tel remplacement n’est généralement pas perceptible à l’œil humain. De plus, de nombreux périphériques de sortie plus anciens ne seront même pas en mesure d'afficher des modifications aussi mineures.

Il est clair que vous pouvez modifier non seulement les 2 bits les moins significatifs, mais n'importe quel nombre d'entre eux. Il existe le schéma suivant : plus nous modifions de bits, plus nous pouvons masquer d'informations et plus cela provoquera d'interférences dans l'image d'origine. Par exemple, voici deux images :

Stéganographie LSB
Stéganographie LSB

Malgré tous mes efforts, je n’ai pas pu voir la différence entre eux, mais néanmoins, dans la deuxième image, en utilisant la méthode décrite, le poème de Lewis Carroll « La chasse au Snark » est caché. Si vous avez lu jusqu'ici, vous êtes probablement intéressé à en savoir plus sur la mise en œuvre. C'est assez simple, mais je vous préviens tout de suite que tout se fait en Delphi. Il y a deux raisons à cela : 1. Je pense que Delphi est un bon langage ; 2. Ce programme est né lors de la préparation d'un cours sur les bases de la vision par ordinateur, et les gars à qui j'enseigne ce cours ne connaissent encore rien d'autre que Delphi. Pour ceux qui ne connaissent pas la syntaxe, une chose doit être expliquée : shl x est un décalage au niveau du bit vers la gauche de x, shr x est un décalage au niveau du bit vers la droite de x.

Nous supposons que nous écrivons du texte stocké dans une chaîne dans le conteneur et que nous remplaçons les deux octets inférieurs :
Code d'enregistrement :

pour i:=1 à length(str) faire
    commencer
      l1:=octet(str[i]) shr 6;
      l2:=byte(str[i]) shl 2; l2:=l2 shr 6;
      l3:=byte(str[i]) shl 4; l3:=l3 shr 6;
      l4:=byte(str[i]) shl 6; l4:=l4 shr 6;
 
      f.ReadBuffer(tmp,1);
      f.Position:=f.Position-1;
      tmp:=((tmp shr 2) shl 2)+l1;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Position:=f.Position-1;
      tmp:=((tmp shr 2) shl 2)+l2;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Position:=f.Position-1;
      tmp:=((tmp shr 2) shl 2)+l3;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Position:=f.Position-1;
      tmp:=((tmp shr 2) shl 2)+l4;
      f.WriteBuffer(tmp,1);
 
    fin;

code à lire :

pour i:=1 à MsgSize, faites
    commencer
      f.ReadBuffer(tmp,1);
      l1:=tmp shl 6 ;
      f.ReadBuffer(tmp,1);
      l2:=tmp shl 6; l2:=l2 shr 2;
      f.ReadBuffer(tmp,1);
      l3:=tmp shl 6; l3:=l3 shr 4;
      f.ReadBuffer(tmp,1);
      l4:=tmp shl 6; l4:=l4 shr 6;
      str:=str+char(l1+l2+l3+l4);
    fin;

Eh bien, pour les vraiment paresseux - lien vers le programme et son code source.

Merci.

Source: habr.com

Ajouter un commentaire