LSB steganograafia

Kaua aega tagasi kirjutasin oma esimese postituse habras. See postitus oli pühendatud üsna huvitavale probleemile, nimelt steganograafiale. Loomulikult ei saa selles vanas teemas pakutud lahendust nimetada steganograafiaks tõelisest sõnas. See on vaid mäng failivormingutega, kuid siiski üsna huvitav mäng.

Täna proovime kaevuda natuke sügavamale ja vaatame LSB algoritmi. Kui see teid huvitab, olete oodatud allapoole. (Allpool on liiklus: umbes megabait.)

Esiteks on vajalik teha väike sissejuhatus. Kõigile on teada, et krüptograafia eesmärk on muuta salajase teabe lugemine võimatuks. Loomulikult on krüptograafial oma rakendusalad, kuid andmete kaitsmiseks on olemas ka teine lähenemine. Ei ole hädavajalik teavet krüptida, vaid võib välja näha, et meil seda pole. Just selleks on välja mõeldud steganograafia. Vikipeedia kinnitab meile, et „steganograafia (kreeka keeles στεγανοσ — varjatud ja kreeka keeles γραφω — kirjutan, sõnasõnaline „salajane kirjutamine”) on teadus peidetud teabe edastamisest, hoides saladuses edastamise fakti.

Loomulikult ei takista keegi krüptograafia ja steganograafia meetodite ühendamist. Tõepoolest, praktikas tehakse seda, kuid meie ülesanne on mõista põhialuseid. Kui lugeda hoolikalt Wikipedia artiklit, võib teada saada, et steganograafia algoritmides on selline asi nagu konteiner ja sõnum. Konteiner on igasugune info, mis aitab peita meie salajast sõnumit.

Meie puhul on konteineriks BMP formaadis pilt. Alustame selle faili struktuuri vaatamisest. Faili võib tinglikult jagada neljaks osaks: faili pea, pildi pea, palett ja ise pilt. Meie eesmärkide jaoks peame teadma ainult seda, mis on kirjas peas.

Esimesed kaks baiti peas on allkiri BM, seejärel on kahekordses sõnas kirjas faili suurus baitides, järgmised 4 baiti on reserveeritud ja peaksid sisaldama nullide, ja lõpuks on veel ühes kahekordses sõnas kirjas nihke arv algusest faili kuni tegelike pildibaitideni. 24-bitises BMP-failis kooditakse iga piksel kolme baitiga BGR.

Nüüd me teame, kuidas pildi juurde jõuda, jääb vaid aru saada, kuidas sinna vajalikku teavet salvestada. Selleks on meil abiks LSB meetod. Meetodi olemus on järgmine: asendame värvikoodimiseks vastutavate baitide madalamad bitid. Oletame, et meie salajase sõnumi järgmine bait on 11001011 ja pildi bait on…11101100 01001110 01111100 0101100111…, siis kodeerimine näeb välja selline. Jagame salajase sõnumi baidi neljaks kahetiseks osaks: 11, 00, 10, 11 ning asendame saadud fragmentidega pildi madalamad bitid: …11101111 01001100 01111110 0101100111…. Selline asendus jääb üldiselt inimese silmale märkamatuks. Veelgi enam, paljud vanad väljundseadmed ei suuda isegi selliseid ebaolulisi muudatusi kuvada.

On selge, et ei muudeta mitte ainult 2 madalamat biti, vaid ka mistahes nende arvu. Siin on järgmine seadus: mida rohkem bitte me muudame, seda rohkem teavet saame peita ja seda suuremad häired see algses pildis põhjustab. Näiteks siin on teile kaks pilti:

LSB steganograafia
LSB steganograafia

Kuidas iganes ma ka ei püüdnud, ei suutnud ma nende vahel erinevust näha, kuid siiski on teises pildis kirjeldatud meetodi abil peidetud Lewis Carrolli luuletus "Hüljatud jahi". Kui olete siiani lugenud, siis on teil kindlasti huvi teada saada ka rakenduse kohta. See on üsna lihtne, kuid hoiatatakse kohe, et kõik on tehtud Delphis. Sellel on kaks põhjust: 1. Pean Delpit heaks ja sobivaks keeleks; 2. See programm sündis masinavaate põhitõdede kursuse ettevalmistamise käigus ja poisid, kellele seda kursust õpetan, ei tea veel midagi peale Delphi. Neile, kes ei tunne süntaksit, tuleks selgitada ühte asja shl x – bitine nihutamine vasakule x võrra, shr x – bitine nihutamine paremale x võrra.

Oletame, et kirjutame konteinerisse teksti, mis on salvestatud real ja asendame alumised kaks baiti:
Kirjutamise kood:

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;

Sulemise kood:

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;

Ja täiesti laiskade jaoks – link programmile ja selle lähtekoodile.

Aitäh.

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster