LSB steganografija

Nekoč sem napisal svoje prva objava na hubu. In ta objava je bila posvečena zelo zanimivemu problemu, in sicer steganografiji. Rešitve, predlagane v tisti stari temi, seveda ne moremo imenovati steganografija v pravem pomenu besede. To je le igra z oblikami datotek, a kljub temu zelo zanimiva igra.

Danes se bomo poskušali poglobiti in pogledati algoritem LSB. Če vas zanima, vabljeni pod kat. (Pod rezom je promet: približno megabajt.)

Najprej je treba narediti kratek uvod. Vsi vedo, da je namen kriptografije onemogočiti branje tajnih informacij. Seveda ima kriptografija svoje aplikacije, vendar obstaja še en pristop k zaščiti podatkov. Podatkov nam ni treba šifrirati, vendar se pretvarjamo, da jih nimamo. Prav zato je bila izumljena steganografija. Wikipedia nam zagotavlja, da je »steganografija (iz grščine στεγανοσ - skrit in grščine γραφω - pišem, dobesedno »skrivno pisanje«) veda o prikritem prenosu informacij tako, da zamolča samo dejstvo prenosa.

Seveda nihče ne prepoveduje kombiniranja kriptografskih in steganografskih metod. Poleg tega v praksi to počnejo, vendar je naša naloga razumeti osnove. Če natančno preučite članek Wikipedije, boste ugotovili, da steganografski algoritmi vključujejo t.i. vsebnik in sporočilo. Vsebnik je vsaka informacija, ki pomaga skriti naše tajno sporočilo.

V našem primeru bo vsebnik slika v formatu BMP. Najprej si poglejmo strukturo te datoteke. Datoteko lahko razdelimo na 4 dele: glavo datoteke, glavo slike, paleto in samo sliko. Za naše namene moramo vedeti le, kaj piše v glavi.

Prva dva bajta glave sta podpis BM, nato je velikost datoteke v bajtih zapisana v dvojni besedi, naslednji 4 bajti so rezervirani in morajo vsebovati ničle, na koncu pa druga dvojna beseda vsebuje odmik od začetka datoteko v dejanske bajte slike. V 24-bitni datoteki bmp je vsaka slikovna pika kodirana s tremi bajti BGR.

Zdaj vemo, kako priti do slike, ostalo je le še razumeti, kako lahko tja zapišemo informacije, ki jih potrebujemo. Za to bomo potrebovali metodo LSB. Bistvo metode je naslednje: v bajtih, ki so odgovorni za barvno kodiranje, zamenjamo najmanj pomembne bite. Recimo, če je naslednji bajt našega tajnega sporočila 11001011 in so bajti na sliki...11101100 01001110 01111100 0101100111..., potem bo kodiranje videti takole. Bajt tajnega sporočila bomo razdelili na 4 dvobitne dele: 11, 00, 10, 11 in zamenjali nižje bite slike z nastalimi fragmenti: ...11101111 01001100 01111110 0101100111…. Takšna zamenjava človeškemu očesu praviloma ni opazna. Poleg tega veliko starejših izhodnih naprav sploh ne bo moglo prikazati tako majhnih sprememb.

Jasno je, da lahko spremenite ne samo 2 najmanj pomembna bita, ampak poljubno število. Obstaja naslednji vzorec: več bitov spremenimo, več informacij lahko skrijemo in več motenj bo to povzročilo v izvirni sliki. Na primer, tukaj sta dve sliki:

LSB steganografija
LSB steganografija

Kljub trudu nisem videl razlike med njima, kljub temu pa se na drugi sliki po opisani metodi skriva pesem Lewisa Carrolla »The Hunting of the Snark«. Če ste prebrali do tukaj, vas verjetno zanima izvajanje. To je precej preprosto, vendar vas bom takoj opozoril, da je vse narejeno v Delphiju. Za to sta dva razloga: 1. Mislim, da je Delphi dober jezik; 2. Ta program se je rodil v procesu priprave tečaja o osnovah računalniškega vida in fantje, ki jim poučujem ta tečaj, še ne poznajo ničesar drugega kot Delphi. Za tiste, ki niso seznanjeni s sintakso, je treba razložiti eno stvar: shl x je bitni premik v levo za x, shr x je bitni premik v desno za x.

Predvidevamo, da v vsebnik pišemo besedilo, shranjeno v nizu, in nadomeščamo spodnja dva bajta:
Koda snemanja:

for i:=1 do length(str) do
    začetek
      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.Pozicija:=f.Položaj-1;
      tmp:=((tmp shr 2) shl 2)+l1;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Pozicija:=f.Položaj-1;
      tmp:=((tmp shr 2) shl 2)+l2;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Pozicija:=f.Položaj-1;
      tmp:=((tmp shr 2) shl 2)+l3;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Pozicija:=f.Položaj-1;
      tmp:=((tmp shr 2) shl 2)+l4;
      f.WriteBuffer(tmp,1);
 
    konec;

koda za branje:

for i:=1 do MsgSize do
    začetek
      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);
    konec;

No, za tiste res lene - povezava do programa in njegove izvorne kode.

Hvala.

Vir: www.habr.com

Dodaj komentar