Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

CACHER UNE SIGNATURE DANS UNE IMAGE


Information sur la source

Catégorie :Sécurité & Cryptage Classé sous : stéganographie Niveau : Débutant Date de création : 02/03/2006 Date de mise à jour : 02/03/2006 22:13:54 Vu : 5 168

Note :
9,75 / 10 - par 8 personnes
9,75 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (15)
Ajouter un commentaire et/ou une note

Description

Cliquez pour voir la capture en taille normale
Voilà, plus un tut de stégano qu'un code: Comment dissimuler une image signature dans une autre image... à quoi ça sert? Ben à publier vos photos de vacances en étant capable de prouver que vous en êtes le proprio si quelqu'un vous les pique pour son site!

Ce code n'est pas utilisable en l'état, il faut customizer, adapter, ...
 

Source

  • <?php
  • // comment prouver qu'on a bien proprio d'une image??? En la signant!
  • // voici le principe de base, il s'agit ensuite de crypter la moindre et d'optimiser les fonctions.
  • // provient d'un formulaire par exemple
  • $signature = 'copyright CS';
  • // 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);
  • // et pour ceux qui ont séché les cours d'algèbre... tant pis :o)
  • 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. Cf image accompagnat la image pour voir un résultat
  • echo '<table><tr><td>Image à dissimuler<br /><img src="sig.png"></td><td>Image à protéger<br /><img src="image.jpg"></td></tr>';
  • echo '<tr><td>Image protégée<br /><img src="signed.png"></td><td>Signature récupérée<br /><img src="back.png"></td></tr></table>';
  • ?>
<?php
// comment prouver qu'on a bien proprio d'une image??? En la signant!
// voici le principe de base, il s'agit ensuite de crypter la moindre et d'optimiser les fonctions.

// provient d'un formulaire par exemple
$signature = 'copyright CS'; 

// 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); 

// et pour ceux qui ont séché les cours d'algèbre... tant pis :o)

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. Cf image accompagnat la image pour voir un résultat
echo '<table><tr><td>Image à dissimuler<br /><img src="sig.png"></td><td>Image à protéger<br /><img src="image.jpg"></td></tr>';
echo '<tr><td>Image protégée<br /><img src="signed.png"></td><td>Signature récupérée<br /><img src="back.png"></td></tr></table>';
?>

Historique

02 mars 2006 22:13:55 :
petite "faute d'erreur" dans les commentaires de corrigée :)

Commentaires et avis

signaler à un administrateur
Commentaire de malalam le 03/03/2006 09:45:56 administrateur CS

Hello Malik,

pas super simple à comprendre, mais très bon source!
Très intéressant, qui plus est, et original (je n'ai pas le souvenir d'en avoir vu beaucoup sur phpcs).
J'aime beaucoup :-)

signaler à un administrateur
Commentaire de malik7934 le 03/03/2006 09:58:46

Une petite explication: chaque pixel d'une image est sur 24 bit. Si un pixel est (255,200,100), ce qui est 11111111 11001000 1100100 en binaire on peut se permettre d'utiliser le bit de poids faible pour soit. En effet, pour l'oeil 11111111 11001000 1100100 et 11111110 11001001 1100101 (254,201,101) par exemple, 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 tu vires les 7 bits de poids fort de l'image signées, il te reste une liste de 0 (à traduire par 00000000) et de 1 (à traduire par 11111111), ce qui donne une image en N/B.

signaler à un administrateur
Commentaire de coucou747 le 03/03/2006 11:04:07

Salut, j'avais fait ça en C, sur des images BMP bits par pixels.
Le problème des .jpegs pour ça, c'est qu'ils sont très très bien compressés, donc, en binaire, ta couleur ne sera plus parfaitement représentée par  bits... Jpeg est comme chacun le sait une compression à perte... Donc, en modifiant le bit de poid faible, tu n'est pas sur que ton message reste... Et en plus, tu verras plus la différence dans une image jpeg que dans une image BMP.... Mais bon, balader du bmp sur internet, c'est pas forcément super car tout le monde sait qu'on cache quelquechose dedans (bah oui, sinon, on aurait mis du jpeg...) Bon, comme tu cré l'image en png, alors t'as moins de perte, mais bon, aparement, tfaçon, tu écris plusieurs fois le message, donc, tu peux toujours le récupérer...

Bref, bonne idée, et ton code est bien commenté, ta source est pas mal.

signaler à un administrateur
Commentaire de malik7934 le 03/03/2006 11:11:38

Si tu fais un essai, tu verras que le problème des couleurs n'a pas lieu d'être car l'image est en fait décompressée avant traitement (si je dis pas de bêtises) et pas "vraiment" recompressée en jpeg (j'avais lu ça je sais pas où...). D'ailleurs, le problème que cela amène est que l'image portant la signature est beaucoup plus lourde que la jpeg d'origine + la signature par exemple...

signaler à un administrateur
Commentaire de coucou747 le 03/03/2006 11:16:47

oki, de toute façon, ça reste moins lourd qu'un BMP...

signaler à un administrateur
Commentaire de Antidote le 06/03/2006 19:54:13

très intéressant, le problème auquel j'ai eu à faire fasse.

On a repris un de mes design (fait sous photoshop) et on l'a retravailler pour l'inscruster dans un autre.

Pensez vous qu'il est possible de retrouver la signature (une parcelle) ? (j'y crois pas)

signaler à un administrateur
Commentaire de malik7934 le 06/03/2006 20:04:35

Hello,
Ca dépend comment il a été retravaillé. Puisque dans le cas présent la signature est répétée ad eternam, s'il y a suffisement de pixels qui n'ont pas été modifiés, alors oui... ceci il existe certainement des techniques bien plus puissantes dans le watermarking :)

signaler à un administrateur
Commentaire de LaurentKOogar le 06/03/2006 20:07:35

J'en rêvais !!
Merci Dude ;-)

signaler à un administrateur
Commentaire de coucou747 le 07/03/2006 07:55:32

regarde tes données exif, t'as pe ton numéro de série de TON logiciel photoshop dedans... Sinon, bah... ouais, faut voir les pixels non modifiés...

signaler à un administrateur
Commentaire de Antidote le 07/03/2006 09:36:30

thanks je ferais un test, je vous dirai ce que ça a donner.

signaler à un administrateur
Commentaire de doudou3158 le 16/04/2006 20:46:42

Sa a l'aire génial mais tu pourrai nous faire un teste qui marche je ne comprend pas ou mettre mon image je ne sais pas quoi pourtant je suis super intéréssé par ta source aide moi stp !

signaler à un administrateur
Commentaire de grosteack le 02/05/2006 16:11:42

J'avais déjà fait çà mais avec une signature non pas en noir et blanc mais en 8 couleurs (rouge, vert, bleu, cyan, magenta, jaune, noir, blanc). En effet, les couleurs sont sur 3 bits. Comme on a trois canaux et donc trois bits de poids faible à chaque pixel de l'image à signer, autant en profiter !
Ma signature on dirait un arc en ciel du coup ;)

Bravo encore pour ton code, c'est utile et original

signaler à un administrateur
Commentaire de MoineCopiste le 19/06/2006 09:54:10

bonjour Malik:
tu dis : [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 :)]
Comme je ne suis pas un super pro ni de la programation ni du graphisme, je me demandai au lu du commentaire à Antidote sur son dessin ... Et que je ne comprends pas bien !
Si tu prends une image qui soit par ton procédé ...
tu la travaille avec des filtres du style "AlphaWorks" ou "Transparency" pour ne citer que cela ... Qui ajissent sur les pixels blanc et noir ???
cela n'interfère en rien ??

Bravo et bonne journée à tous

signaler à un administrateur
Commentaire de malik7934 le 19/06/2006 10:01:46

Y a de très fortes chances que si tu passes des filtres sur une image signée avec mon code, le code soit bousillé. C'est un système de signature basique, il n'est pas fait pour résister aux modifications (il y en a qui le font).

signaler à un administrateur
Commentaire de MoineCopiste le 19/06/2006 10:20:22

Merci de cette réponse rapide , c'est juste pour comprendre ...
Car j'utilise beaucoup ces filtres pour mes composition...
ça va j'ai compris et je repond a Antidote et confirme les dires de Coucou !
une image sur le web pour la "garder" perso ce n'est pas simple ..
Par contre j'avais lu je ne sais plus oi je me fais vieux ...
qu'en ouvrant les sources d'une image il y a de la place pour y mettre un code ...
mais en jpg c'est détruit à 90%...
Merci bonne semaine à tous

Ajouter un commentaire



Nos sponsors

Sondage...

CalendriCode

Janvier 2009
LMMJVSD
   1234
567891011
12131415161718
19202122232425
262728293031 

Consulter la suite du CalendriCode



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel BAÏSE, Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 1,139 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.