CACHER UNE SIGNATURE DANS UNE IMAGE |
Sténographie d'images |
|
 |
Si la cryptographie est l'art du secret, la stéganographie est l'art de la dissimulation ...
A quoi sert ce code ? A publier par exemple vos photos de vacances en étant capable de prouver que vous en êtes le propriétaire si quelqu'un vous les vole.
Ce code est fonctionnel mais n'est pas utilisable en l'état, il faut le customizer, l'adapter à vos besoins ...
|
Une petite explication:
Chaque pixel d'une image est sur 24 bit. Si un pixel est (255,200,100), ce qui donne (11111111 11001000 1100100) en binaire, on peut se permettre d'utiliser le ce que l'on appelle le bit de poids faible.
En effet, pour l'oeil (11111111 11001000 1100100) et (11111110 11001001 1100101) soit (254,201,101), c'est kif-kif-bourricot!
Du coup, on stocke l'image "signature" avec le dernier bit: - chaque fois que c'est un pixel blanc, on met à 1 - chaque fois que c'est un pixel noir on met à 0 ... et on ne voit pas de différence :)
Du coup, si vous virez les 7 bits de poids fort de l'image signées, il vous reste une liste de 0 (à traduire par 00000000) et de 1 (à traduire par 11111111), ce qui donne comme résultat une image en Noir et Blanc.
<?php
// Comment prouver qu'on est bien proprio d'une image??? // En la signant!
// provient d'un formulaire par exemple $signature = 'Copyright Visualight 2006';
// pour faire lisible $signature = '* '.$signature.' *';
// on récupère la taille de l'image à signer qui est image.jpg ici // (image dans mon répertoire courant en l'occurence) $im_prot = imagecreatefromjpeg('image.jpg'); list($width,$height) = getimagesize('image.jpg');
// on crée la signature en fonction. // Il s'agit d'une image en noir et blanc avec le message $signature en redondance // (ceux qui suivent comprendront pourquoi l'image DOIT être en noir et blanc...)
$sig= imagecreate($width, $height); $bg = imagecolorallocate($sig, 255, 255, 255); $tc = imagecolorallocate($sig, 0, 0, 0);
// Pour la redondance, on part du principe qu'un caractère prend 5 pixels de large et 10 de haut $sig_size = round($width/(strlen($signature)*5)); for ($i = 0;$i< $sig_size;$i++) $signature .= $signature;
$sig_size = round($height/10); for ($i = 0;$i< $sig_size;$i++) imagestring($sig, 1, 5, 5+$i*10, $signature, $tc);
// l'image de signature est prête. imagepng($sig,'sig.png');
// on va signer... $image = imagecreatetruecolor($width,$height);
for ($i=0;$i<$width;$i++) { for ($j=0;$j<$height;$j++) {
// on récupère rgb de l'image à signer $rgb = imagecolorat($im_prot,$i,$j); $r=($rgb>>16)&0xFF; $g=($rgb>>8)&0xFF; $b=$rgb&0xFF;
// et celui de la signature $rgb = imagecolorat($sig,$i,$j);
// si c'est 0 on met le bit de droite à 0 à r, g et b (rappel: 8 bits chacun) if ($rgb == 0){
// xxxxxxx0 AND 11111110 = xxxxxxx0 // xxxxxxx1 AND 11111110 = xxxxxxx0
$r = $r&0xFE; $g = $g&0xFE; $b = $b&0xFE;
// si c'est 1, on met le bit de droite à 1 à r, g et b } else { // xxxxxxx0 OR 00000001 = xxxxxxx1 // xxxxxxx1 OR 00000001 = xxxxxxx1
$r=$r|1; $g=$g|1; $b=$b|1; } $color = imagecolorallocate($image,$r,$g,$b); imagesetpixel($image,$i,$j,$color); }}
// voici l'image portant la signature imagepng($image, 'signed.png');
/**************************************************/
// Maintenant, on va faire le chemin inverse et récupérer la signature dissimulée
$protected_pic = imagecreatefrompng('signed.png'); list($width,$height) = getimagesize('signed.png');
$restored_sig = imagecreatetruecolor($width,$height);
for ($i=0;$i<$width;$i++) { for ($j=0;$j<$height;$j++) {
$rgb=imagecolorat($protected_pic,$i,$j);
// on regarde chaque rgb, // si xxxxxxxy & 1 = 0, c'est que le dernier bit y est à 0. // si xxxxxxxy & 1 = 1, c'est que le dernier bit y est à 1.
$r=($rgb>>16)&0xFF; $g=($rgb>>8)&0xFF; $b=$rgb&0xFF;
// on fait donc comme avant, mais dans l'autre sens! if(($r&1)==0) $r=255;else $r=0; if(($g&1)==0) $g=255;else $g=0; if(($b&1)==0) $b=255;else $b=0;
$color=imagecolorallocate($restored_sig,$r,$g,$b); imagesetpixel($restored_sig,$i,$j,$color); }}
imagepng($restored_sig,'back.png'); // et voilà !
// affichage des résultats. echo '<table><tr><td>Image à dissimuler<br />'; echo '<img src="sig.png"></td><td>Image à protéger<br /><img src="image.jpg"></td></tr>'; echo '<tr><td>Image protégée<br />'; echo '<img src="signed.png"></td><td>Signature récupérée<br /><img src="back.png"></td></tr></table>';
?>
|
Voilà comment on profite des "faiblesses" du php et de l''oeil humain à son avantage ;)
Bonne Prog ;)
Amicalement, Visualight
|