LSB-steganografie

Ooit schreef ik mijn eerste bericht op Hub. En dat bericht was gewijd aan een heel interessant probleem, namelijk steganografie. Natuurlijk kan de oplossing die in dat oude onderwerp wordt voorgesteld niet steganografie in de ware zin van het woord worden genoemd. Het is gewoon een spel met bestandsformaten, maar toch een behoorlijk interessant spel.

Vandaag zullen we proberen wat dieper te graven en naar het LSB-algoritme te kijken. Bij interesse bent u welkom onder cat. (Onder de snede zit verkeer: ongeveer een megabyte.)

Allereerst is het noodzakelijk om een ​​korte introductie te maken. Iedereen weet dat het doel van cryptografie is om het lezen van geheime informatie onmogelijk te maken. Natuurlijk heeft cryptografie zijn toepassingen, maar er is een andere benadering van gegevensbescherming. We hoeven de informatie niet te versleutelen, maar doen alsof we deze niet hebben. Dit is precies waarom steganografie werd uitgevonden. Wikipedia verzekert ons dat “steganografie (van het Griekse στεγανοσ – verborgen en het Griekse γραφω – ik schrijf, letterlijk “geheim schrijven”) de wetenschap is van de verborgen overdracht van informatie door het feit van de overdracht geheim te houden.

Natuurlijk verbiedt niemand het combineren van cryptografische en steganografische methoden. Bovendien doen ze dit in de praktijk, maar het is onze taak om de basisprincipes te begrijpen. Als je het Wikipedia-artikel zorgvuldig bestudeert, zul je ontdekken dat steganografische algoritmen de zogenaamde. houder en boodschap. Een container is alle informatie die onze geheime boodschap helpt verbergen.

In ons geval zal de container een afbeelding in BMP-formaat zijn. Laten we eerst eens kijken naar de structuur van dit bestand. Het bestand kan in 4 delen worden verdeeld: bestandskop, afbeeldingskop, palet en de afbeelding zelf. Voor onze doeleinden hoeven we alleen te weten wat er in de koptekst staat.

De eerste twee bytes van de header zijn de BM-handtekening, vervolgens wordt de bestandsgrootte in bytes geschreven in een dubbel woord, de volgende 4 bytes zijn gereserveerd en moeten nullen bevatten, en ten slotte bevat een ander dubbel woord de offset vanaf het begin van de header. bestand naar de daadwerkelijke bytes van de afbeelding. In een 24-bits bmp-bestand wordt elke pixel gecodeerd met drie BGR-bytes.

Nu weten we hoe we bij de afbeelding kunnen komen, het enige dat overblijft is begrijpen hoe we de informatie die we daar nodig hebben kunnen schrijven. Hiervoor hebben we de LSB-methode nodig. De essentie van de methode is als volgt: we vervangen de minst significante bits in de bytes die verantwoordelijk zijn voor kleurcodering. Laten we zeggen dat de volgende byte van ons geheime bericht 11001011 is, en de bytes in de afbeelding zijn...11101100 01001110 01111100 0101100111..., dan zal de codering er als volgt uitzien. We zullen de geheime berichtbyte opsplitsen in 4 delen van twee bits: 11, 00, 10, 11, en de lage-orde bits van de afbeelding vervangen door de resulterende fragmenten: ...11101111 01001100 01111110 0101100111…. Een dergelijke vervanging is doorgaans niet waarneembaar voor het menselijk oog. Bovendien zullen veel oudere uitvoerapparaten dergelijke kleine wijzigingen niet eens kunnen weergeven.

Het is duidelijk dat je niet alleen de twee minst significante bits kunt veranderen, maar een willekeurig aantal daarvan. Er is het volgende patroon: hoe meer bits we veranderen, hoe meer informatie we kunnen verbergen, en hoe meer interferentie dit zal veroorzaken in het originele beeld. Hier zijn bijvoorbeeld twee afbeeldingen:

LSB-steganografie
LSB-steganografie

Ondanks mijn inspanningen kon ik het verschil tussen hen niet zien, maar toch is in de tweede afbeelding, met behulp van de beschreven methode, het gedicht van Lewis Carroll "The Hunting of the Snark" verborgen. Als je dit tot nu toe hebt gelezen, ben je waarschijnlijk geïnteresseerd in de implementatie ervan. Het is vrij eenvoudig, maar ik waarschuw je meteen dat alles in Delphi wordt gedaan. Daar zijn twee redenen voor: 1. Ik vind Delphi een goede taal; 2. Dit programma is ontstaan ​​tijdens het voorbereiden van een cursus over de basisprincipes van computer vision, en de jongens aan wie ik deze cursus geef, kennen nog niets anders dan Delphi. Voor degenen die niet bekend zijn met de syntaxis, moet één ding worden uitgelegd: shl x is een bitsgewijze verschuiving naar links over x, shr x is een bitsgewijze verschuiving naar rechts over x.

We gaan ervan uit dat we tekst die in een string is opgeslagen in de container schrijven en de onderste twee bytes vervangen:
Opnamecode:

voor i:=1 tot lengte(str) doen
    beginnen
      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.Positie:=f.Positie-1;
      tmp:=((tmp shr 2) shl 2)+l1;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Positie:=f.Positie-1;
      tmp:=((tmp shr 2) shl 2)+l2;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Positie:=f.Positie-1;
      tmp:=((tmp shr 2) shl 2)+l3;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Positie:=f.Positie-1;
      tmp:=((tmp shr 2) shl 2)+l4;
      f.WriteBuffer(tmp,1);
 
    einde te maken;

code om te lezen:

for i:=1 tot MsgSize doen
    beginnen
      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);
    einde te maken;

Nou, voor de echt luie mensen - link naar het programma en de broncode.

Dank u.

Bron: www.habr.com

Voeg een reactie