LSB szteganográfia

Egyszer régen megírtam az én első bejegyzés a hubon. És ezt a bejegyzést egy nagyon érdekes problémának szentelték, nevezetesen a szteganográfiának. Természetesen az abban a régi témában javasolt megoldás nem nevezhető szteganográfiának a szó valódi értelmében. Ez csak egy játék fájlformátumokkal, de ennek ellenére elég érdekes játék.

Ma megpróbálunk egy kicsit mélyebbre ásni, és megvizsgáljuk az LSB algoritmust. Ha érdekel, várjuk a cat alá. (A vágás alatt a forgalom: körülbelül egy megabájt.)

Mindenekelőtt egy rövid bevezetőt kell készíteni. Mindenki tudja, hogy a kriptográfia célja, hogy lehetetlenné tegye a titkos információk olvasását. Természetesen a kriptográfiának megvannak a maga alkalmazásai, de van egy másik megközelítés is az adatvédelemben. Nem kell titkosítanunk az információt, hanem úgy teszünk, mintha nem rendelkeznénk vele. Pontosan ezért találták fel a szteganográfiát. A Wikipédia biztosít minket arról, hogy „a szteganográfia (a görög στεγανοσ - rejtett és a görög γραφω - én írom, szó szerint "titkos írás") tudománya az információ rejtett továbbításának tudománya azáltal, hogy az átvitel tényét titokban tartja.

Természetesen senki sem tiltja a kriptográfiai és szteganográfiai módszerek kombinálását. Ráadásul a gyakorlatban ezt meg is teszik, de a mi feladatunk az alapok megértése. Ha figyelmesen áttanulmányozza a Wikipédia cikket, rájön, hogy a szteganográfiai algoritmusok között szerepel az ún. konténer és üzenet. A konténer minden olyan információ, amely segít elrejteni titkos üzenetünket.

Esetünkben a tároló egy BMP formátumú kép lesz. Először is nézzük meg ennek a fájlnak a szerkezetét. A fájl 4 részre osztható: fájlfejléc, képfejléc, paletta és maga a kép. Célunkhoz csak azt kell tudnunk, hogy mi van a fejlécben.

A fejléc első két bájtja a BM aláírás, majd a fájl mérete bájtban dupla szóban van írva, a következő 4 bájt le van foglalva és nullákat kell tartalmaznia, végül egy másik dupla szó tartalmazza az eltolást a fájlt a kép tényleges bájtjaira. Egy 24 bites bmp fájlban minden képpont három BGR bájttal van kódolva.

Most már tudjuk, hogyan juthatunk el a képhez, csak azt kell megérteni, hogyan írhatjuk oda a szükséges információkat. Ehhez szükségünk lesz az LSB módszerre. A módszer lényege a következő: a színkódolásért felelős bájtokban a legkisebb jelentőségű biteket cseréljük ki. Tegyük fel, hogy ha titkos üzenetünk következő bájtja 11001011, és a képen lévő bájtok...11101100 01001110 01111100 0101100111..., akkor a kódolás így fog kinézni. A titkos üzenet bájtját felosztjuk 4 kétbites részre: 11, 00, 10, 11, és a kép alacsony rendű bitjeit a kapott töredékekre cseréljük: ...11101111 01001100 01111110 0101100111… Az ilyen csere az emberi szem számára általában nem észrevehető. Ráadásul sok régebbi kimeneti eszköz nem is képes ilyen kisebb változtatásokat megjeleníteni.

Nyilvánvaló, hogy nem csak a 2 legkisebb jelentőségű bitet módosíthatja, hanem tetszőleges számút. A következő minta van: minél több bitet változtatunk, annál több információt tudunk elrejteni, és ez annál nagyobb interferenciát okoz az eredeti képben. Például itt van két kép:

LSB szteganográfia
LSB szteganográfia

Minden igyekezetem ellenére nem láttam a különbséget köztük, de ennek ellenére a második képen a leírt módszerrel Lewis Carroll „A Snark vadászata” című verse rejtőzik. Ha idáig elolvasta, valószínűleg érdekli a megvalósítás. Nagyon egyszerű, de azonnal figyelmeztetlek, hogy minden a Delphiben megtörtént. Ennek két oka van: 1. Szerintem a Delphi egy jó nyelv; 2. Ez a program a számítógépes látás alapjairól szóló tanfolyam előkészítése során született, és a srácok, akiknek ezt a kurzust tartom, még nem tudnak semmit a Delphi-n kívül. Azok számára, akik nem ismerik a szintaxist, egy dolgot kell elmagyarázni: az shl x bitenkénti eltolás x-szel balra, az shr x bitenkénti eltolás x-szel jobbra.

Feltételezzük, hogy egy karakterláncban tárolt szöveget írunk a tárolóba, és lecseréljük az alsó két bájtot:
Felvételi kód:

for i:=1 to long(str) do
    kezdődik
      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.Pozíció:=f.Pozíció-1;
      tmp:=((tmp shr 2) shl 2)+l1;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Pozíció:=f.Pozíció-1;
      tmp:=((tmp shr 2) shl 2)+l2;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Pozíció:=f.Pozíció-1;
      tmp:=((tmp shr 2) shl 2)+l3;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Pozíció:=f.Pozíció-1;
      tmp:=((tmp shr 2) shl 2)+l4;
      f.WriteBuffer(tmp,1);
 
    end;

leolvasható kód:

i:=1 esetén MsgSize do
    kezdődik
      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;

Nos, az igazán lustáknak... link a programhoz és annak forráskódjához.

Köszönöm.

Forrás: will.com

Hozzászólás