LSB steganografia

Kedysi dávno som napísal svoj prvý príspevok na habre. Tento príspevok bol venovaný veľmi zaujímavej problematike, a to steganografii. Samozrejme, riešenie navrhnuté v tej starej téme nemožno považovať za steganografiu v pravom slova zmysle. Je to len hra s formátmi súborov, ale aj tak je to veľmi zaujímavá hra.

Dnes sa pokúsime ísť o niečo hlbšie a preskúmame algoritmus LSB. Ak vás to zaujíma, srdečne vás pozývam pod čiaru. (Pod čiarou je prenos: približne megabajt.)

Predovšetkým je potrebné urobiť malé úvodné slovo. Všetkým je známe, že účelom kryptografie je znemožniť čítanie tajných informácií. Samozrejme, kryptografia má svoje oblasti uplatnenia, ale existuje aj iný prístup k ochrane dát. Môžeme nešifrovať informácie, ale jednoducho predstierať, že ich nemáme. Práve na tento účel bola vymyslená steganografia. Wikipédia nás ubezpečuje, že "steganografia (z gréckeho στεγανοσ — skrytý a gréckeho γραφω — píšem, doslova 'tajné písanie') je veda o skrytých prenosoch informácií prostredníctvom utajenia samotného faktu prenosu.

Samozrejme, nikto nezakazuje kombinovať kryptografické a steganografické metódy. Ba naopak, v praxi sa to robí, ale našou úlohou je pochopiť základy. Ak si pozorne prečítate článok na Wikipédii, zistíte, že v algoritmoch steganografie vystupuje tzv. kontajner a správa. 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 si priblížime štruktúru tohto súboru. Súbor môžeme zjednodušene rozdeliť na 4 časti: hlavička súboru, hlavička obrázka, paleta a samotný obrázok. Naše ciele poznajú iba to, čo je napísané v hlavičke.

Prvé dva bajty hlavičky sú podpis BM, ďalej je v dvojitom slove zapísaná veľkosť súboru v bajtoch, ďalšie 4 bajty sú rezervované a mali by obsahovať nuly, a nakoniec, v ďalšom dvojitom slove je zapísané posunutie od začiatku súboru k samotným bajtom obrázku. V 24-bitovom bmp súbore je každý pixel kódovaný tromi bajtmi BGR.

Teraz už vieme, ako sa dostať k obrázku, teraz musíme zistiť, ako doň zapísať potrebné informácie. Na to nám poslúži metóda LSB. Podstata metódy je nasledovná: nahradíme najnižšie bity v bajtoch, ktoré sa používajú na kódovanie farby. Predpokladajme, že ak bajt našej tajnej správy je 11001011, a bajty v obrázku sú…11101100 01001110 01111100 0101100111…, kódovanie bude vyzerať takto. Rozdelíme bajt tajnej správy na 4 dvojbitové časti: 11, 00, 10, 11, a nahradíme nimi najnižšie bity obrázka: …11101111 01001100 01111110 0101100111…. Takáto zmena nie je zvyčajne viditeľná pre ľudské oko. Navyše, mnohé staré výstupné zariadenia nemusia vykazovať také nepatrné zmeny.

Je jasné, že môžeme meniť nielen 2 najnižšie bity, ale aj akékoľvek ich množstvo. Tu existuje nasledujúca zákonitosť: čím viac bitov meníme, tým väčší objem informácií môžeme skryť, a tým väčšie rušenie to spôsobí v pôvodnom obrázku. Pre príklad tu máte dve obrázky:

LSB steganografia
LSB steganografia

Napriek všetkému som si tak a tak nevedel všimnúť rozdiel medzi nimi, a predsa v druhom obrázku bola pomocou opísanej metódy skrytá báseň Lewisa Carrolla „Lov na Snarka“. Ak ste dočítali až sem, určite vás zaujíma aj realizácia. Je to celkom jednoduché, ale hneď varujem, že celé to je napísané na Delphi. Dôvody sú dva: 1. Verím, že Delphi je dobrý, hodnotný jazyk; 2. Tento program vznikol v procese prípravy kurzu o základoch počítačového videnia, a študenti, ktorým tento kurz prednášam, zatiaľ nepoznajú nič iné ako Delphi. Pre tých, ktorí nie sú oboznámení so syntaxou, treba vysvetliť jednu vec shl x – bitový posun doľava o x, shr x – bitový posun doprava o x.

Predpokladajme, že zapisujeme do kontajnera text, ktorý je uložený v reťazci a nahrádzame najnižšie dva bajty:
Kód pre zápis:

for i:=1 to length(str) do
    begin
      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.Position:=f.Position-1;
      tmp:=((tmp shr 2) shl 2)+l1;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Position:=f.Position-1;
      tmp:=((tmp shr 2) shl 2)+l2;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Position:=f.Position-1;
      tmp:=((tmp shr 2) shl 2)+l3;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Position:=f.Position-1;
      tmp:=((tmp shr 2) shl 2)+l4;
      f.WriteBuffer(tmp,1);
 
    end;

kód pre čítanie:

for i:=1 to MsgSize do
    begin
      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;

No a pre úplne lenivých – odkaz na program a jeho zdrojový kód.

Ďakujem.

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster