LSB steganografi

For a long time, I wrote my first post on Habr. That post was dedicated to a very interesting problem, namely steganography. Of course, the solution proposed in that old topic cannot be called steganography in the true sense of the word. It's merely a play with file formats, but still a rather interesting game.

Today, we will try to dig a little deeper and look at the LSB algorithm. If you're interested, feel free to read more below. (Below the break, the traffic is about a megabyte.)

First of all, it is necessary to make a small introduction. It is well known that the purpose of cryptography is to make it impossible to read secret information. Of course, cryptography has its areas of application, but there is also another approach to data protection. Instead of encrypting the information, one can pretend that we do not have it. This is exactly what steganography was invented for. Wikipedia assures us that 'steganography (from Greek στεγανοσ — hidden and γραφω — I write, literally 'secret writing') is the science of hidden information transmission by keeping the fact of transmission itself secret.

Of course, no one forbids combining cryptographic and steganographic methods. Moreover, in practice, this is indeed what is done, but our task is to understand the fundamentals. If you carefully study the article from Wikipedia, you can find that algorithms of steganography feature a so-called container and a message. The container is any information that helps hide our secret message.

In our case, the container will be an image in BMP format. First, let's look at the structure of this file. The file can be conditionally divided into four parts: the file header, the image header, the palette, and the image itself. For our purposes, we only need to know what is recorded in the header.

The first two bytes of the header are the signature BM, followed by a double word that indicates the file size in bytes, the next 4 bytes are reserved and must contain zeros, and finally, in another double word is recorded the offset from the start of the file to the actual image bytes. In a 24-bit bmp file, each pixel is encoded with three bytes of BGR.

Nå vet vi hvordan vi kommer til bildet, det gjenstår å forstå hvordan vi kan skrive nødvendig informasjon dit. For dette vil metoden LSB være til hjelp. Metoden er enkel: vi erstatter de laveste bitene i byte som ansvarer for fargekodingen. Anta at byte for vår hemmelige melding er 11001011, og byte i bildet er …11101100 01001110 01111100 0101100111…, så vil koding se slik ut. Vi deler byte av den hemmelige meldingen inn i 4 to-bits deler: 11, 00, 10, 11, og erstatter de laveste bitene i bildet med de oppnådde fragmentene: …11101111 01001100 01111110 0101100111…. Slik bytte er vanligvis ikke merkbart for det menneskelige øye. Videre vil mange eldre utdataenheter ikke klare å vise slike ubetydelige endringer.

Det er klart at man kan endre ikke bare 2 laveste biter, men hvilket som helst antall. Her er det en viktig regel: jo flere biter vi endrer, jo mer informasjon kan vi skjule, og jo større forstyrrelser dette vil forårsake i det originale bildet. For eksempel her er to bilder:

LSB steganografi
LSB steganografi

Uansett hvor mye jeg prøvde, klarte jeg ikke å se forskjellen mellom dem, men likevel er det i det andre bildet skjult et dikt av Lewis Carroll, «Jakten på Snark». Hvis du har lest så langt, lurer du sikkert på implementeringen. Den er ganske enkel, men jeg advarer på forhånd om at alt er gjort på Delphi. Årsaken til dette er to: 1. Jeg anser Delphi som et godt og nyttig språk; 2. Dette programmet ble laget i prosessen med å forberede et kurs om grunnleggende maskinsyn, og de gutta jeg underviser dette kurset for, vet foreløpig ingenting annet enn Delphi. For de som ikke er kjent med syntaksen, må jeg forklare en ting: shl x – bitforskyvning til venstre med x, shr x – bitforskyvning til høyre med x.

La oss si at vi skriver innholdet som tekst i en streng og erstatter de laveste to bitene:
Kode for skriving:

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;

kode for lesing:

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;

Og for de helt late – lenke til programmet og kildekoden.

Takk.

Kilde: habr.com

Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere 🔥 Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere | ProHoster