Introduction
Une technique fréquemment utilisée en stéganographie pour cacher des informations est la technique du Least Significant Bit, LSB ou bits de poids faible. Contrairement à mon article sur le padding BMP, cette méthode peut être utilisée sur plusieurs formats d'images, tant que celui-ci n'utilise pas de compression avec perte. Il est donc possible de l'utiliser sur les formats BMP, PNG, GIFF... mais ne pourra pas être appliquée au format JPG. L'objectif du LSB est de modifier de façon imperceptible l'image pour cacher de l'information.Principe
Pour commencer il est nécessaire de comprendre comment sont stockées les informations dans une image. Chaque image est constituée de pixels codés généralement par 3 couleurs : rouge, vert et bleu (RGB). Chaque pixel représente donc une certaine quantité de rouge, une certaine quantité de vert et une certaine quantité de bleue.Si on prend le cas ou chaque couleur de chaque pixel est codée sur un octet il y a donc 256 valeurs pour une couleur de 0 (la couleur n'est pas présente) à 255.
On peut donc représenter 256^3 soit 16777216 couleurs au total. L'idée est que l'œil humain ne va pas être capable de distinguer parfaitement toutes ces couleurs et que donc de légères modifications sur la couleur des pixels ne seront pas distinguables en tout cas pour l'œil humain.
Prenons un exemple, la couleur suivante est constituée uniquement de rouge et a la valeur 255,0,0 (255 de rouge, 0 de vert et 0 de bleu), la suivante a la valeur 254,0,0.
Représentation binaire
Le but est donc de trouver un moyen d'altérer la couleur de l'image d'une façon imperceptible. Cette technique va se baser sur la représentation du nombre en binaire. Comme dit précédemment, une couleur est codée sur un octet, soit 8 bits. On peut donc représenter n'importe quelle couleur par une suite de 8 bits. Ce qui est intéressant dans cette approche c'est que chaque bit n'est pas porteur de la même quantité d'information. Le bit de poids faible (le bit le plus à droite) a un poids de 1, c'est à dire que le fait qu'il soit à 1 ou à 0 ne modifiera la valeur finale que de 1, alors que le bit de poids fort (le bit le plus à gauche) a un poids de 128.Le tableau suivant détaille le poids de chaque bit :
Représentation binaire de 153 = 10011001b
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 | |
---|---|---|---|---|---|---|---|---|
Valeur binaire | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 |
Poids du bit | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
Pour vérifier : 153 = 1*128 + 0*64 + 0*32 + 1*16 + 1*8 + 0*4 + 0*2 + 1*1
L'idée finale est donc d'altérer les bits qui portent le moins d'informations pour y stocker notre message caché. Etant donné que ces bits sont porteurs de peu d'information, l'aspect visuel de l'image sera peu altéré.
Cacher de l'information
Prenons un exemple concret où nous voulons cacher la lettre "A" dans 3 pixels. Les 3 pixels seront 153,74,186 255,255,255 0,0,0. La lettre "A" a la valeur ASCII 65 soit 01000001b en binaire. Comme dit précédemment, on va modifier les bits de poids faible de chaque couleur pour stocker notre information.Pixel 1 Rouge | Pixel 1 Vert | Pixel 1 Bleu | Pixel 2 Rouge | Pixel 2 Vert | Pixel 2 Bleu | Pixel 3 Rouge | Pixel 3 Vert | Pixel 3 Bleu | |
---|---|---|---|---|---|---|---|---|---|
Valeur Décimale | 153 | 74 | 186 | 255 | 255 | 255 | 0 | 0 | 0 |
Valeur Binaire | 10011001 | 01001010 | 10111011 | 11111111 | 11111111 | 11111111 | 00000000 | 00000000 | 00000000 |
Bit à cacher | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | padding |
Couleur finale binaire | 10011000 | 01001011 | 10111010 | 11111110 | 11111110 | 11111110 | 00000000 | 00000001 | 00000000 |
Couleur finale | 152 | 75 | 186 | 254 | 254 | 254 | 0 | 1 | 0 |
La nouvelle suite de couleur passe à 152,75,186 254,254,254 0,1,0. Comme on peut donc le voir, une légère modification a lieu.
Bien joué pour la série d'articles sur la stégano, j'ai jamais réellement trouvé d'infos dans ce domaine là sur Internet (soit elles sont bien cachées, soit je suis une bille, au choix), mais je trouve ça bien d'expliquer quelques techniques :)
RépondreSupprimerJ'essaierais de pondre un article ou deux là dessus, une fois que j'aurais fini la Webapp 8 de a NdH
Enjoy
The lsd
Clair et bien expliqué pour des débutants comme moi en stégano.
RépondreSupprimerN'hésite pas à faire de nouveaux articles comme cette série d'articles sur la stégano.
Shp
"L'image suivante possède une information cachée dans ses bits de poids de faible"
RépondreSupprimerJe souhaiterais volontiers avoir plus d'info dessus, car j'ai retourné l'image dans tous les sens et je ne vois rien! D'ailleurs, statistiquement, l'image ne semble pas cacher d'information sur ses bits de poids faible(peu de "bruit")
Est-ce une erreur de ma part ou bien l'image n'est pas cache effectivement rien?
@keutru
RépondreSupprimerJe me réponds à moi même, y'a effectivement du bruit sur l'image pouvant caractériser une information cachée. Je n'le voyais pas initialemement à cause du fonctionnement plutôt surprenant d'image magick(via Perl), les valeures RGB obtenues via les fonctions Image::Magick::GetPixel sont en fait les valeurs RGB originales multipliées par 257.... Allez comprendre...
Je n'ai toujours pas trouvé ce que cachait cette image et donc les complément d'infos sont toujours les bienvenus!
Normalement ce n'est pas compliqué :) Tu prends les derniers bits de chaque composante de chaque pixel et tu mets tout ça dans un fichier. Ne t'attends pas à trouver une phrase compréhensible ;)
RépondreSupprimerN'hésites pas à me dire si tu ne trouves toujours pas.
@time0ut
RépondreSupprimerMerci pour ta réponse.
J'ai retenté ma chance et pfiou! C'est bon :):), mais ce fut laborieux! Après la surprise du facteur 257 pour Image::Magick, j'en avais oublié de retester les choses simples, j'étais parti à parcourir les pixels dans un sens ou dans un autre, à considérer que finalement (d'après l'article) il y avait vraiment un bit de padding chaque 3 pixels, ou encore que les bits récupérés étaient donné dans l'ordre LSB Firstaulieu de MSBF!
Pour ceux cherchant encore: faites simple!
Note: pour ceux travaillant avec GD (et Perl en tout cas), n'oubliez pas d'activer les 'TrueColors' à l'ouverture de votre image, et pour ceux travaillage avec Image::Magick voyez mon commentaire ci-dessus.