LSB steganografia

Kedysi dávno som napísal svoje prvý príspevok na hube. A ten príspevok bol venovaný veľmi zaujímavému problému, a to steganografii. Samozrejme, riešenie navrhované v tej starej téme nemožno nazvať steganografiou v pravom zmysle slova. Je to len hra s formátmi súborov, no napriek tomu je to celkom zaujímavá hra.

Dnes sa pokúsime kopať trochu hlbšie a pozrieť sa na algoritmus LSB. Ak máte záujem, ste vítaní pod kat. (Pod rezom je návštevnosť: asi megabajt.)

V prvom rade je potrebné urobiť krátky úvod. Každý vie, že účelom kryptografie je znemožniť čítanie tajných informácií. Samozrejme, kryptografia má svoje aplikácie, ale existuje aj iný prístup k ochrane údajov. Informácie nemusíme šifrovať, ale predstierať, že ich nemáme. To je presne dôvod, prečo bola vynájdená steganografia. Wikipedia nás uisťuje, že „steganografia (z gréčtiny στεγανοσ – skrytý a grécky γραφω – píšem, doslova „tajné písanie“) je veda o skrytom prenose informácií udržiavaním v tajnosti samotnej skutočnosti prenosu.

Samozrejme, nikto nezakazuje kombinovať kryptografické a steganografické metódy. Navyše to v praxi robia, ale našou úlohou je pochopiť základy. Ak si pozorne preštudujete článok na Wikipédii, zistíte, že medzi steganografické algoritmy patria tzv. kontajnera a správy. Kontajner je akákoľvek informácia, ktorá pomáha skryť našu tajnú správu.

V našom prípade bude kontajnerom obrázok vo formáte BMP. Najprv sa pozrime na štruktúru tohto súboru. Súbor je možné rozdeliť na 4 časti: hlavička súboru, hlavička obrázka, paleta a samotný obrázok. Pre naše účely nám stačí vedieť, čo je napísané v hlavičke.

Prvé dva bajty hlavičky sú podpis BM, potom sa veľkosť súboru v bajtoch zapíše dvojitým slovom, ďalšie 4 bajty sú vyhradené a musia obsahovať nuly a nakoniec ďalšie dvojité slovo obsahuje posun od začiatku súbor na skutočné bajty obrázka. V 24-bitovom súbore bmp je každý pixel zakódovaný tromi bajtmi BGR.

Teraz vieme, ako sa k obrázku dostať, zostáva už len pochopiť, ako tam môžeme napísať potrebné informácie. Na to budeme potrebovať metódu LSB. Podstata metódy je nasledovná: nahrádzame najmenej významné bity v bajtoch zodpovedných za farebné kódovanie. Povedzme, že ak je nasledujúci bajt našej tajnej správy 11001011 a bajty na obrázku sú...11101100 01001110 01111100 0101100111..., potom bude kódovanie vyzerať takto. Bajt tajnej správy rozdelíme na 4 dvojbitové časti: 11, 00, 10, 11 a nahradíme bity nižšieho rádu výslednými fragmentmi: ...11101111 01001100 01111110 0101100111…. Takáto náhrada je vo všeobecnosti pre ľudské oko nepostrehnuteľná. Navyše, mnohé staršie výstupné zariadenia ani nebudú schopné zobraziť takéto drobné zmeny.

Je jasné, že zmeniť môžete nielen 2 najmenej významné bity, ale ľubovoľný počet z nich. Existuje nasledujúci vzorec: čím viac bitov zmeníme, tým viac informácií môžeme skryť a tým viac interferencií to spôsobí v pôvodnom obrázku. Tu sú napríklad dva obrázky:

LSB steganografia
LSB steganografia

Napriek môjmu najlepšiemu úsiliu som medzi nimi nevidel rozdiel, no napriek tomu je na druhom obrázku opísanou metódou skrytá báseň Lewisa Carrolla „Lov na Snark“. Ak ste sa dočítali až sem, pravdepodobne máte záujem dozvedieť sa viac o implementácii. Je to celkom jednoduché, ale hneď vás upozorním, že všetko sa robí v Delphi. Sú na to dva dôvody: 1. Myslím si, že Delphi je dobrý jazyk; 2. Tento program sa zrodil v procese prípravy kurzu základov počítačového videnia a chalani, ktorým tento kurz vediem, zatiaľ nepoznajú nič iné ako Delphi. Pre tých, ktorí nie sú oboznámení so syntaxou, je potrebné vysvetliť jednu vec: shl x je bitový posun doľava o x, shr x je bitový posun doprava o x.

Predpokladáme, že do kontajnera zapisujeme text uložený v reťazci a nahrádzame spodné dva bajty:
Záznamový kód:

for i:=1 to length(str) do
    začať
      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ícia:=f.Pozícia-1;
      tmp:=((tmp shr 2) shl 2)+1;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Pozícia:=f.Pozícia-1;
      tmp:=((tmp shr 2) shl 2)+2;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Pozícia:=f.Pozícia-1;
      tmp:=((tmp shr 2) shl 2)+3;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Pozícia:=f.Pozícia-1;
      tmp:=((tmp shr 2) shl 2)+4;
      f.WriteBuffer(tmp,1);
 
    end;

kód na prečítanie:

for i:=1 až MsgSize do
    začať
      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(1+2+3+4);
    end;

No pre tých naozaj lenivých... odkaz na program a jeho zdrojový kód.

Ďakujem.

Zdroj: hab.com

Pridať komentár