Projektowanie stron WWW od podszewki
Losowy artykuł: Recenzja edytora EdHTML

Artykuły na każdy temat

[PHP][GD] Zapisywanie "ukrytych" informacji w plikach graficznych

Dodano 31.10.2013r. o 23:14
Po tym jak zrobiłem zegarek binarny w wersji PHP przy użyciu GD. Przyszła kolej na następny eksperyment. Tym razem zapisywanie "ukrytych informacji" w grafikach. Przy założeniu, że jeden piksel to 3 wartości tj. czerwony, zielony i niebieski można sobie szybko wyobrazić jaką "optymalizację" otrzymujemy na starcie. Oczywiście można jeszcze doliczyć 4 parametr tj. o ile mnie pamięć nie myli jest nią saturacja. W każdym bądź razie po próbnych testach pokazałem grafikę Sobakowi, a ten mi mówi, że przez zwykły edytor tekstowy można podejrzeć zawartość "zakodowanego" ciągu znaków (mowa o tym pliku graficznym). Faktycznie można było to uczynić, jeżeli użyto imagecreate() zamiast imagecreatetruecolor(). Polecam sprawdzić osobiście przy użyciu dłuższego ciągu znaków niż proponowany. Zauważycie szybko, że po określonej ilości znaków treść zostaje ucięta w zawartości pikseli. Ponadto do przeprowadzenia testu wypadałoby zakomentować fragment odpowiedzialny za delokacje zadeklarowanego koloru, czyli użycie funkcji imagecolordeallocate(). Przy użyciu drugiej funkcji która została wymieniona powyżej grafika wygląda następująco natomiast po podejrzeniu pliku przez zwykły edytor tekstowy wygląda właśnie tak. Następne, co dowiedziałem się o tym, co przygotowałem to to, że z jakieś dwa lata temu zostało to "opisane" tutaj.

Wracając do sedna sprawy index.php wygląda tak:
Kod:
<?php
$path './test.png';
$data 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Proin nibh augue, suscipit a, scelerisque sed, lacinia in, mi. Cras vel lorem. Etiam pellentesque aliquet tellus. Phasellus pharetra nulla ac diam. Quisque semper justo at risus. Donec venenatis, turpis vel hendrerit interdum, dui ligula ultricies purus, sed posuere libero dui id orci. Nam congue, pede vitae dapibus aliquet, elit magna vulputate arcu, vel tempus metus leo non est. Etiam sit amet lectus quis est congue mollis. Phasellus congue lacus eget neque. Phasellus ornare, ante vitae consectetuer consequat, purus sapien ultricies dolor, et mollis pede metus eget nisi. Praesent sodales velit quis augue. Cras suscipit, urna at aliquam rhoncus, urna quam viverra nisi, in interdum massa nibh nec erat.';
include('./img.class.php');

$img = new img();
// Zapisywanie tekstu w grafice
var_dump($img -> encode($data$path));
// Odczytywanie tekstu z grafiki
var_dump($img -> decode($path));
?>
a cała klasa tak:
Kod:
<?php
class img
{
 private $max_width 500;
 private $offset;
 private $data;
 private $path;
 private $key;
 private $key_length;

 public function encode($data$path$key '')
 {
  if(empty($data))
  {
   return false;
  }
  else
  {
   $this -> offset 0;
   $this -> data $data;
   $this -> path $path;

   if(!empty($key))
   {
    $this -> key $key;
    $this -> key_length count($key);
   }
  }

  $x $y 0;
  $length[0] = strlen($this -> data);
  $length[1] = $length[0] / 3;
  $size[0] = ($length[1] > $this -> max_width $this -> max_width ceil($length[1]));
  $size[1] = ($length[1] <= $this -> max_width ceil($length[1] / $this -> max_width));
  $size[2] = $size[0] - 1;
  $im imagecreatetruecolor($size[0], $size[1]);
  $background_color imagecolorallocate($im255255255);
  imagefill($im00$background_color);

  while($this -> offset $length[0])
  {
   $rgb $this -> calculate_color();
   $color imagecolorallocate($im$rgb[0], $rgb[1], $rgb[2]);
   imagesetpixel($im$x$y $color);
   imagecolordeallocate($im$color);

   if($x $size[2])
   {
    ++$x;
   }
   else
   {
    $x 0;
    ++$y;
   }
  }

  $is_saved imagepng($im$this -> path);
  imagedestroy($im);

  return $is_saved;
 }

 public function decode($path$key '')
 {
  if(!file_exists($path))
  {
   return false;
  }
  else
  {
   $this -> offset 0;
   $this -> path $path;
   $this -> data '';

   if(!empty($key))
   {
    $this -> key $key;
    $this -> key_length count($key);
   }
  }

  $im imagecreatefrompng($this -> path);
  $size getimagesize($this -> path);

  for($y 0$y $size[1]; ++$y)
  {
   for($x 0$x $size[0]; ++$x)
   {
    $rgb imagecolorat($im$x$y);
    $this -> data .= $this -> decode_pixel($rgb);

    if($this -> offset == -1)
    {
     break(2);
    }
   }
  }

  imagedestroy($im);

  return $this -> data;
 }

 private function calculate_color()
 {
  for($h 0$h 3; ++$h, ++$this -> offset)
  {
   $color[] = ord($this -> data[$this -> offset]) ^ $this -> key[$this -> offset $this -> key_length];
  }

  return $color;
 }

 private function decode_pixel($rgb)
 {
  $color[] = ($rgb >> 16) & 0xFF;
  $color[] = ($rgb >> 8) & 0xFF;
  $color[] = $rgb 0xFF;

  for($h 0$h 3; ++$h, ++$this -> offset)
  {
   $color[$h] = $color[$h] ^ $this -> key[$this -> offset $this -> key_length];

   if($color[$h] != 0)
   {
    $data .= chr($color[$h]);
   }
   else
   {
    $this -> offset = -1;

    break;
   }
  }

  return $data;
 }
}
?>
Po szybkiej analizie wyłapiecie pewnie, że w metodach odpowiedzialnych za zapis i odczyt występuję parametr $key, który jest niejako nawiązaniem do ostatniego artykułu czyli szyfrowania przy pomocy XOR. Przy wykorzystaniu klucza można niejako utrudnić odczyt takiej grafiki.

Komentarze

Brak komentarzy

Dodaj komentarz

Zostaw komentarz jeżeli możesz! Nie bądź przysłowiowym botem! Nie bądź obojętny! Ciebie to nic nie kosztuje, a mi sprawi uśmiech na twarzy.
Zezwolono używać: BBCode
Zabroniono używać:
znaczników HTML

(Wymagany)

(Wymagany, niepublikowany)

(Nie wymagana)

Token:

Obrazek dla bota

(Przepisz tylko cyfry!)

(Wymagana)