Nekada davno napisao sam svoj . Taj post bio je posvećen vrlo zanimljivoj temi, a to je steganografija. Naravno, rješenje predloženo u toj staroj temi ne može se nazvati steganografijom u pravom smislu te riječi. To je samo igra s formatima datoteka, ali, ipak, vrlo zanimljiva igra.
Danas ćemo pokušati malo dublje zaroniti i razmotriti LSB algoritam. Ako vas zanima, slobodno prođite ispod. (Ispod ima prometa: oko megabajta.)
Prije svega, potrebno je napraviti mali uvod. Svi znaju da je svrha kriptografije onemogućiti čitanje tajnih informacija. Naravno, kriptografija ima svoje sfere primjene, ali postoji i drugi pristup zaštiti podataka. Može se ne šifrirati informacija, već učiniti da izgleda kao da je nemamo. Upravo zbog toga je stvorena steganografija. Wikipedia nas uvjerava da "steganografija (od grčkog στεγανοσ — skriveno i grčkog γραφω — pišem, doslovno 'tajnopis') — to je znanost o skrivenom prijenosu informacija putem skrivanja samog čina prijenosa.
Naravno, nitko ne zabranjuje kombiniranje kriptografskih i steganografskih metoda. Štoviše, u praksi je to tako i učinjeno, ali naš zadatak je razjasniti osnove. Ako pažljivo proučite članak s Wikipedije, možete saznati da u algoritmima steganografije figurišu tzv. kontejner i poruka. Kontejner — to je svaka informacija koja pomaže prikrivenju naše tajne poruke.
U našem slučaju kontejner će biti slika u BMP formatu. Za početak, razmotrit ćemo strukturu te datoteke. Datoteku možemo uvjetno podijeliti na 4 dijela: zaglavlje datoteke, zaglavlje slike, paletu i samu sliku. Za naše potrebe potrebno je znati samo ono što je zapisano u zaglavlju.
Prva dva bajta zaglavlja predstavljaju potpis BM, zatim u dvostrukom word-u zapisan je veličina datoteke u bajtovima, sljedeća 4 bajta su rezervirana i trebaju sadržavati nule, a konačno, u još jednom dvostrukom word-u zapisano je pomak od početka datoteke do vlastitih bajtova slike. U 24-bitnom bmp-datoteci svaki piksel se kodira s tri bajta BGR.
Sada znamo kako doći do slike, preostaje nam da shvatimo kako u nju zapisati potrebne informacije. Za to će nam koristiti metoda LSB. Suština metode leži u sledećem: zamenjujemo najmanje bitove u bajtovima koji odgovaraju za kodiranje boje. Pretpostavimo da je bajt naše tajne poruke – 11001011, a bajtovi u slici –…11101100 01001110 01111100 0101100111…, tada će kodiranje izgledati ovako. Podelićemo bajt tajne poruke na četiri dela po dva bita: 11, 00, 10, 11, i zameniti dobijenim fragmentima najmanje bitove slike: …11101111 01001100 01111110 0101100111…. Ova zamena u opštem slučaju nije primetna ljudskom oku. Štaviše, mnogi stari uređaji za prikazivanje možda neće moći da prikažu tako neznatne promene.
Jasno je da ne možemo menjati samo 2 najmanja bita, već i bilo koji njihov broj. Tu postoji sledeća zakonitost: što veći broj bitova menjamo, to veći obim informacija možemo sakriti, i to će izazvati veće smetnje u originalnoj slici. Kao primer, evo dve slike:


I pored sve želje, nisam uspeo da uočim razliku između njih, a ipak je u drugoj slici uz pomoć opisane metode skrivena pesma Luisa Karola „Lov na Snarka“. Ako ste do ovde pročitali, sigurno vas zanima i realizacija. Ona je prilično jednostavna, ali odmah upozoravam da je sve urađeno u Delphi-u. Razlozi su dva: 1. Smatram da je Delphi dobar i upotrebljiv jezik; 2. Ovaj program je nastao tokom pripreme kursa o osnovama mašinskog vida, a momcima kojima to predajem, za sada ništa drugo osim Delphi-a nije poznato. Za one koji nisu upoznati sa sintaksom, treba da pojasnim jednu stvar shl x – bitovni pomak ulevo za x, shr x – bitovni pomak udesno za x.
Pretpostavljamo da zapisujemo u kontejner tekst koji se čuva u stringu i zamenjujemo najmanje dva bita:
Kod za zapisivanje:
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;
kod za čitanje:
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;
Pa za potpuno lenje – .
Hvala.
Izvor: habr.com
