LSB steganografija

Nekoč sem napisal svoj prvi prispevek na habru. Ta prispevek je bil posvečen zelo zanimivi težavi, in sicer steganografiji. Seveda rešitve, predstavljene v tistem starem prispevku, ne morem imenovati steganografija v pravem pomenu besede. To je le igra s formati datotek, toda kljub temu zelo zanimiva igra.

Danes bomo poskušali raziskati malo globlje in si podrobneje ogledali algoritem LSB. Če vas zanima, ste vabljeni pod zavihkom. (Pod zavihkom je promet: približno megabajt.)

Predvsem je potrebno narediti majhen uvod. Vsem je znano, da je namen kriptografije onemogočiti branje tajnih informacij. Seveda ima kriptografija svoja področja uporabe, vendar obstaja tudi drug pristop k zaščiti podatkov. Informacij ne moremo šifrirati, lahko pa se pretvarjamo, da jih nimamo. Prav to je razlog, zakaj je bila izumljena steganografija. Wikipedia nas prepričuje, da je 'steganografija (iz grščine στεγανοσ — skrit in grščine γραφω — pišem, dobesedno 'tajnopis') znanost o skriti prenosu informacij z obdržanjem samega dejstva prenosa v skrivnosti.

Seveda nihče ne prepoveduje kombiniranja kriptografskih in steganografskih metod. Še več, v praksi tako tudi počnejo, vendar je naš cilj, da razjasnimo osnove. Če natančno preučite članek na Wikipediji, lahko ugotovite, da se v algoritmih steganografije pojavljata t. i. kontejner in sporočilo. Kontejner je kakršna koli informacija, ki pomaga skriti naše skrivno sporočilo.

V našem primeru bo kontejner slika v formatu BMP. Za začetek si oglejmo strukturo te datoteke. Datoteko lahko pogojno razdelimo na 4 dele: glavo datoteke, glavo slike, paleto in samo sliko. Za naše potrebe je potrebno vedeti le to, kar je zapisano v glavi.

Prva dva bajta glave sta podpis BM, nato pa je v dvojni besedi zapisana velikost datoteke v bajtih, naslednji 4 bajti so rezervirani in morajo vsebovati ničle, in končno, v še eni dvojni besedi je zapisano odstopanje od začetka datoteke do pravih bajtov slike. V 24-bitnem bmp-datoteki je vsak piksel kodiran s tremi bajti BGR.

Zdaj imamo informacije o tem, kako pridobiti sliko, zdaj pa moramo razumeti, kako vanjo zapisati potrebne podatke. Zato nam bo pomagal metoda LSB. Essence metode je naslednja: zamenjamo najnižje bite v bajtih, ki so odgovorni za kodiranje barve. Predpostavimo, da je trenutni bajt naše skrivne sporočila – 11001011, bajti v sliki pa –…11101100 01001110 01111100 0101100111…, zato bo kodiranje izgledalo takole. Razdelili bomo bajt skrivne sporočila na 4 dva bita: 11, 00, 10, 11, in zamenjali najnižje bite slike: …11101111 01001100 01111110 0101100111…. Takšna zamenjava običajno ni opazna človeškemu očesu. Še več, mnoge stare naprave za izhod, sploh ne bodo mogle prikazati tako majhnih sprememb.

Očitno je, da lahko spreminjamo ne samo 2 najnižja bita, temveč tudi poljubno število le-teh. Tu velja naslednje pravilo: boljše je število bitov, ki jih spreminjamo, večji obseg informacij lahko skrijemo in večje motnje v izvirni sliki bo to povzročilo. Na primer, tukaj sta dve sliki:

LSB steganografija
LSB steganografija

Ob vsej želji nisem mogel videti razlike med njima, kljub temu pa je v drugi sliki s pomočjo opisane metode skrita pesem Lewisa Carrolla 'Lov na Snarka'. Če ste prišli do te točke, vas verjetno zanima tudi implementacija. Ta je precej preprosta, vendar takoj opozarjam, da je vse narejeno v Delphi. Razlogov za to sta dva: 1. Menim, da je Delphi dober in uporaben jezik; 2. Ta program je nastal med pripravo tečaja o osnovah strojnega vida, in fantje, katerim ta tečaj predavam, zaenkrat ne poznajo nič drugega kot Delphi. Za tiste, ki niso seznanjeni s sintakso, naj pojasnim eno stvar shl x – bitni premik levo za x, shr x – bitni premik desno za x.

Predpostavljamo, da zapisujemo v vsebnik besedilo, shranjeno v nizu, in zamenjujemo spodnja dva bajta:
Koda za zapis:

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;

koda za branje:

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 in za čisto lene – povezava do programa in njegovega izvornega kode.

Hvala.

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster