Il y a longtemps, j'ai écrit mon . Cet article était dédié à un problème très intéressant, à savoir la stéganographie. Bien sûr, la solution proposée dans ce vieux fil ne peut pas vraiment être qualifiée de stéganographie au sens propre du terme. C'est simplement un jeu avec des formats de fichiers, mais néanmoins, c'est un jeu assez intéressant.
Aujourd'hui, nous allons tenter d'aller un peu plus loin et d'explorer l'algorithme LSB. Si cela vous intéresse, je vous invite sous le toit. (Sous le toit, le trafic : environ un mégaoctet.)
Tout d'abord, il est nécessaire de faire une petite 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 domaines d'application, mais il existe également une autre approche pour protéger les données. On peut ne pas chiffrer l'information, mais faire semblant que nous ne l'avons pas. C'est exactement pour cela que la stéganographie a été inventée. Wikipédia nous assure que « la stéganographie (du grec στεγανοσ — caché et du grec γραφω — écrire, littéralement « écriture secrète ») est la science de la transmission cachée d'informations en maintenant secrète l'existence même de la transmission.
Bien sûr, personne n'interdit de combiner des méthodes cryptographiques et stéganographiques. De plus, en pratique, c'est ce qui se fait, mais notre tâche est de comprendre les bases. Si nous étudions attentivement l'article de Wikipédia, nous pouvons apprendre que dans les algorithmes de stéganographie, on trouve le fameux conteneur et message. Le conteneur — c'est toute information qui aide à cacher notre message secret.
Dans notre cas, le conteneur sera une image au format BMP. Pour commencer, examinons la structure de ce fichier. Le fichier peut être conditionnellement 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, il suffit de savoir ce qui est inscrit dans l'en-tête.
Les deux premiers octets de l'en-tête sont la signature BM, ensuite, dans un mot double, est indiqué la taille du fichier en octets, les 4 octets suivants sont réservés et doivent contenir des zéros et, enfin, dans un autre mot double, est inscrit le décalage depuis le début du fichier jusqu'aux octets d'image eux-mêmes. Dans un fichier BMP 24 bits, chaque pixel est codé par trois octets BGR.
Maintenant, nous savons comment accéder à l'image, il ne reste plus qu'à comprendre comment y enregistrer les informations nécessaires. Pour cela, la méthode LSB nous sera utile. Le principe de la méthode est le suivant : nous remplaçons les bits de poids faible dans les octets responsables du codage des couleurs. Supposons que l'octet de notre message secret soit 11001011, et les octets dans l'image soient… 11101100 01001110 01111100 0101100111…, alors le codage 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 ces fragments : …11101111 01001100 01111110 0101100111…. Ce remplacement est, en général, invisible à l'œil humain. De plus, de nombreux anciens dispositifs d'affichage ne pourront même pas afficher de tels changements minimes.
Il est clair que l'on peut changer non seulement 2 bits de poids faible, mais aussi n'importe quel nombre d'entre eux. Il existe une règle : plus nous changeons de bits, plus le volume d'informations que nous pouvons cacher est grand, et plus cela provoquera de perturbations dans l'image d'origine. Par exemple, voici deux images :


Malgré mes efforts, je n'ai pas réussi à percevoir de différence entre elles, néanmoins, dans la deuxième image, un poème de Lewis Carroll, « La Chasse au Snark », est caché par la méthode décrite. Si vous avez lu jusqu'ici, vous êtes sûrement curieux de connaître l'implémentation. Elle est assez simple, mais je préviens tout de suite que tout a été fait en Delphi. Pour deux raisons : 1. Je considère 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 étudiants à qui je donne ce cours ne connaissent pour l'instant que Delphi. Pour ceux qui ne sont pas familiarisés avec la syntaxe, je tiens à préciser une chose : shl x – décalage binaire à gauche de x, shr x – décalage binaire à droite de x.
Supposons que nous écrivions dans le conteneur du texte stocké dans une chaîne et remplaçons les deux derniers bits :
Code pour l'écriture :
for i:=1 to length(str) do
begin
l1:=byte(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);
end;
code pour la lecture :
for i:=1 to MsgSize do
begin
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);
end;
Et pour les vraiment paresseux – .
Merci.
Source : habr.com
