LSB steganograafia

Kunagi ammu kirjutasin oma esimene postitus keskuses. Ja see postitus oli pühendatud väga huvitavale probleemile, nimelt steganograafiale. Muidugi ei saa tolles vanas teemas pakutud lahendust nimetada steganograafiaks selle sõna otseses tähenduses. See on lihtsalt failivormingutega mäng, kuid päris huvitav mäng sellegipoolest.

Täna proovime veidi süveneda ja vaadata LSB algoritmi. Huvi korral olete oodatud kassi alla. (Lõike all on liiklus: umbes megabait.)

Kõigepealt on vaja teha lühike sissejuhatus. Kõik teavad, et krüptograafia eesmärk on muuta salajase teabe lugemine võimatuks. Muidugi on krüptograafial oma rakendused, kuid andmekaitsel on ka teine ​​lähenemine. Me ei pea teavet krüpteerima, vaid teeskleme, et meil seda pole. Täpselt seetõttu leiutati steganograafia. Wikipedia kinnitab meile, et "steganograafia (kreeka keelest στεγανοσ - varjatud ja kreeka keelest γραφω - ma kirjutan, sõna otseses mõttes "salajane kirjutamine") on teadus teabe varjatud edastamisest, hoides edastamise fakti saladuses.

Muidugi ei keela keegi krüptograafilisi ja steganograafilisi meetodeid kombineerida. Pealegi teevad nad seda praktikas, kuid meie ülesanne on mõista põhitõdesid. Kui uurite hoolikalt Vikipeedia artiklit, saate teada, et steganograafia algoritmid sisaldavad nn. konteiner ja sõnum. Konteiner on igasugune teave, mis aitab varjata meie salajast sõnumit.

Meie puhul on konteiner BMP-vormingus pilt. Kõigepealt vaatame selle faili struktuuri. Faili saab jagada 4 ossa: faili päis, pildi päis, palett ja pilt ise. Oma eesmärkidel peame teadma ainult seda, mis on päises kirjutatud.

Päise esimesed kaks baiti on BM-signatuur, seejärel kirjutatakse faili suurus baitides topeltsõnaga, järgmised 4 baiti on reserveeritud ja peavad sisaldama nulle ning lõpuks sisaldab veel üks topeltsõna nihet faili algusest. faili pildi tegelikele baitidele. 24-bitises bmp-failis on iga piksel kodeeritud kolme BGR-baidiga.

Nüüd teame, kuidas pildini jõuda, jääb üle vaid mõista, kuidas saame sinna vajalikku infot kirjutada. Selleks vajame LSB meetodit. Meetodi olemus on järgmine: asendame värvikodeeringu eest vastutavates baitides kõige vähem olulised bitid. Oletame, et kui meie salasõnumi järgmine bait on 11001011 ja pildil olevad baidid on...11101100 01001110 01111100 0101100111..., siis näeb kodeering välja selline. Jagame salasõnumibaidi neljaks kahebitiseks osaks: 4, 11, 00, 10 ja asendame pildi madalama järgu bitid saadud fragmentidega: ...1111 01001100 01111110 0101100111… Selline asendus pole üldjuhul inimsilmale märgatav. Lisaks ei suuda paljud vanemad väljundseadmed isegi selliseid väiksemaid muudatusi kuvada.

On selge, et saate muuta mitte ainult kaht kõige vähemtähtsat bitti, vaid suvalist arvu neist. Siin on järgmine muster: mida rohkem bitte muudame, seda rohkem teavet saame peita ja seda rohkem häireid see algses pildis põhjustab. Näiteks siin on kaks pilti:

LSB steganograafia
LSB steganograafia

Vaatamata pingutustele ei suutnud ma nende vahel vahet näha, kuid sellegipoolest on teisel pildil kirjeldatud meetodil peidus Lewis Carrolli luuletus “Snarki jaht”. Kui olete siiani lugenud, siis olete tõenäoliselt huvitatud juurutamise kohta õppimisest. See on üsna lihtne, kuid ma hoiatan teid kohe, et kõik on Delfis tehtud. Sellel on kaks põhjust: 1. Minu arvates on Delphi hea keel; 2. See programm sündis arvutinägemise aluste kursuse koostamise käigus ja need tüübid, kellele ma seda kursust annan, ei tea veel midagi peale Delphi. Neile, kes süntaksiga kursis ei ole, tuleb selgitada üht: shl x on nihe x võrra vasakule, shr x on nihe x võrra paremale.

Eeldame, et kirjutame konteinerisse stringina salvestatud teksti ja asendame kaks alumist baiti:
Salvestuskood:

for i:=1 kuni pikkus(str) tee
    alustama
      l1:=bait(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.Asend:=f.Asend-1;
      tmp:=((tmp shr 2) shl 2)+l1;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Asend:=f.Asend-1;
      tmp:=((tmp shr 2) shl 2)+l2;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Asend:=f.Asend-1;
      tmp:=((tmp shr 2) shl 2)+l3;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Asend:=f.Asend-1;
      tmp:=((tmp shr 2) shl 2)+l4;
      f.WriteBuffer(tmp,1);
 
    lõppu;

kood lugemiseks:

i:=1 puhul MsgSize teha
    alustama
      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);
    lõppu;

Noh, tõeliselt laiskadele - link programmile ja selle lähtekoodile.

Aitäh.

Allikas: www.habr.com

Lisa kommentaar