LSB steganografie

Kdysi dávno jsem napsal svůj první příspěvek na hubu. A ten příspěvek byl věnován velmi zajímavému problému, a to steganografii. Řešení navržené v onom starém tématu samozřejmě nelze nazvat steganografií v pravém slova smyslu. Je to jen hra s formáty souborů, ale přesto docela zajímavá hra.

Dnes se pokusíme zapátrat trochu hlouběji a podívat se na algoritmus LSB. Pokud máte zájem, jste vítáni pod kat. (Pod řezem je provoz: asi megabajt.)

Nejprve je nutné udělat krátký úvod. Každý ví, že účelem kryptografie je znemožnit čtení tajných informací. Samozřejmě, že kryptografie má své aplikace, ale existuje i jiný přístup k ochraně dat. Nemusíme informace šifrovat, ale předstírat, že je nemáme. To je přesně důvod, proč byla vynalezena steganografie. Wikipedie nás ujišťuje, že „steganografie (z řeckého στεγανοσ – skrytý a řeckého γραφω – píšu, doslova „tajné psaní“) je věda o skrytém přenosu informace tím, že samotný fakt přenosu zůstává v tajnosti.

Samozřejmě nikdo nezakazuje kombinovat kryptografické a steganografické metody. Navíc to v praxi dělají, ale naším úkolem je pochopit základy. Pokud si pozorně prostudujete článek na Wikipedii, zjistíte, že steganografické algoritmy zahrnují tzv. kontejner a zpráva. Kontejner je jakákoliv informace, která pomáhá skrýt naši tajnou zprávu.

V našem případě bude kontejnerem obrázek ve formátu BMP. Nejprve se podívejme na strukturu tohoto souboru. Soubor lze rozdělit na 4 části: záhlaví souboru, záhlaví obrázku, paletu a samotný obrázek. Pro naše účely nám stačí vědět, co je napsáno v záhlaví.

První dva bajty hlavičky jsou podpis BM, pak se velikost souboru v bajtech zapíše dvojslovem, další 4 bajty jsou rezervované a musí obsahovat nuly a nakonec další dvojslovo obsahuje posun od začátku souboru na skutečné bajty obrázku. V 24bitovém souboru bmp je každý pixel zakódován třemi bajty BGR.

Nyní víme, jak se k obrázku dostat, zbývá jen pochopit, jak tam můžeme zapsat potřebné informace. K tomu budeme potřebovat metodu LSB. Podstata metody je následující: nahrazujeme nejméně významné bity v bytech odpovědných za barevné kódování. Řekněme, že pokud je další bajt naší tajné zprávy 11001011 a bajty v obrázku jsou...11101100 01001110 01111100 0101100111..., pak bude kódování vypadat takto. Byte tajné zprávy rozdělíme na 4 dvoubitové části: 11, 00, 10, 11 a nahradíme bity nižšího řádu výslednými fragmenty: ...11101111 01001100 01111110 0101100111…. Taková náhrada není obecně lidským okem patrná. Navíc mnoho starších výstupních zařízení nebude schopno takové drobné změny ani zobrazit.

Je jasné, že změnit můžete nejen 2 nejméně významné bity, ale libovolný počet z nich. Existuje následující vzorec: čím více bitů změníme, tím více informací můžeme skrýt a tím větší interferenci to způsobí v původním obrázku. Zde jsou například dva obrázky:

LSB steganografie
LSB steganografie

Přes veškerou snahu jsem mezi nimi neviděl rozdíl, ale přesto je na druhém obrázku popsanou metodou skryta báseň Lewise Carrolla „Lov na Snark“. Pokud jste dočetli až sem, pak máte pravděpodobně zájem dozvědět se o implementaci. Je to docela jednoduché, ale hned vás upozorním, že vše se dělá v Delphi. Jsou pro to dva důvody: 1. Myslím, že Delphi je dobrý jazyk; 2. Tento program se zrodil v procesu přípravy kurzu základů počítačového vidění a kluci, kterým tento kurz vedu, zatím neznají nic jiného než Delphi. Pro ty, kteří nejsou obeznámeni se syntaxí, je třeba vysvětlit jednu věc: shl x je bitový posun doleva o x, shr x je bitový posun doprava o x.

Předpokládáme, že do kontejneru zapisujeme text uložený v řetězci a nahrazujeme spodní dva bajty:
Záznamový kód:

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

kód ke čtení:

for i:=1 to MsgSize do
    začít
      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, pro ty opravdu líné... odkaz na program a jeho zdrojový kód.

Děkuju.

Zdroj: www.habr.com

Přidat komentář