LSB-Steganographie

Es war einmal, als ich meine schrieb erster Beitrag auf Hub. Und dieser Beitrag war einem sehr interessanten Problem gewidmet, nämlich der Steganographie. Natürlich kann die in diesem alten Thema vorgeschlagene Lösung nicht im eigentlichen Sinne Steganographie genannt werden. Es ist nur ein Spiel mit Dateiformaten, aber dennoch ein ziemlich interessantes Spiel.

Heute werden wir versuchen, etwas tiefer zu graben und uns den LSB-Algorithmus anzusehen. Bei Interesse sind Sie gerne unter Kat. willkommen. (Unter dem Schnitt liegt Datenverkehr: etwa ein Megabyte.)

Zunächst ist eine kurze Einleitung erforderlich. Jeder weiß, dass der Zweck der Kryptographie darin besteht, das Lesen geheimer Informationen unmöglich zu machen. Natürlich hat die Kryptographie ihre Anwendungen, aber es gibt noch einen anderen Ansatz für den Datenschutz. Wir müssen die Informationen nicht verschlüsseln, sondern so tun, als hätten wir sie nicht. Genau aus diesem Grund wurde die Steganographie erfunden. Wikipedia versichert uns, dass „Steganographie (von griechisch στεγανοσ – verborgen und griechisch γραφω – ich schreibe, wörtlich „geheimes Schreiben“) die Wissenschaft der verborgenen Übermittlung von Informationen ist, indem die eigentliche Tatsache der Übermittlung geheim gehalten wird.

Natürlich verbietet niemand die Kombination kryptografischer und steganografischer Verfahren. Darüber hinaus tun sie dies in der Praxis, aber unsere Aufgabe ist es, die Grundlagen zu verstehen. Wenn Sie den Wikipedia-Artikel sorgfältig studieren, werden Sie feststellen, dass Steganographie-Algorithmen das sogenannte umfassen. Container und Nachricht. Ein Container ist jede Information, die dabei hilft, unsere geheime Botschaft zu verbergen.

In unserem Fall ist der Container ein Bild im BMP-Format. Schauen wir uns zunächst die Struktur dieser Datei an. Die Datei kann in 4 Teile unterteilt werden: Dateikopf, Bildkopf, Palette und das Bild selbst. Für unsere Zwecke müssen wir nur wissen, was in der Kopfzeile steht.

Die ersten beiden Bytes des Headers sind die BM-Signatur, dann wird die Dateigröße in Bytes in ein Doppelwort geschrieben, die nächsten 4 Bytes sind reserviert und müssen Nullen enthalten und schließlich enthält ein weiteres Doppelwort den Offset vom Anfang des Headers Datei in die tatsächlichen Bytes des Bildes um. In einer 24-Bit-BMP-Datei ist jedes Pixel mit drei BGR-Bytes codiert.

Jetzt wissen wir, wie wir zum Bild gelangen. Jetzt müssen wir nur noch verstehen, wie wir die benötigten Informationen dorthin schreiben können. Dazu benötigen wir die LSB-Methode. Der Kern der Methode ist wie folgt: Wir ersetzen die niedrigstwertigen Bits in den für die Farbkodierung verantwortlichen Bytes. Nehmen wir an, wenn das nächste Byte unserer geheimen Nachricht 11001011 ist und die Bytes im Bild ... 11101100 01001110 01111100 0101100111 ... lauten, dann sieht die Codierung so aus. Wir werden das geheime Nachrichtenbyte in 4 Zwei-Bit-Teile aufteilen: 11, 00, 10, 11, und die niederwertigen Bits des Bildes durch die resultierenden Fragmente ersetzen: ...11101111 01001100 01111110 0101100111…. Für das menschliche Auge ist ein solcher Ersatz in der Regel nicht wahrnehmbar. Darüber hinaus sind viele ältere Ausgabegeräte nicht einmal in der Lage, solche geringfügigen Änderungen anzuzeigen.

Es ist klar, dass Sie nicht nur die 2 niedrigstwertigen Bits ändern können, sondern beliebig viele davon. Es gibt das folgende Muster: Je mehr Bits wir ändern, desto mehr Informationen können wir verbergen und desto mehr Störungen werden dadurch im Originalbild verursacht. Hier zum Beispiel zwei Bilder:

LSB-Steganographie
LSB-Steganographie

Trotz aller Bemühungen konnte ich den Unterschied zwischen ihnen nicht erkennen, aber dennoch ist im zweiten Bild mit der beschriebenen Methode Lewis Carrolls Gedicht „The Hunting of the Snark“ verborgen. Wenn Sie bis hierher gelesen haben, sind Sie wahrscheinlich daran interessiert, mehr über die Implementierung zu erfahren. Es ist ganz einfach, aber ich warne Sie gleich, dass alles in Delphi erledigt wird. Dafür gibt es zwei Gründe: 1. Ich denke, Delphi ist eine gute Sprache; 2. Dieses Programm entstand im Zuge der Vorbereitung eines Kurses über die Grundlagen des Computer Vision, und die Leute, denen ich diesen Kurs unterrichte, kennen noch nichts anderes als Delphi. Für diejenigen, die mit der Syntax nicht vertraut sind, muss eines erklärt werden: shl x ist eine bitweise Verschiebung um x nach links, shr x ist eine bitweise Verschiebung um x nach rechts.

Wir gehen davon aus, dass wir in einem String gespeicherten Text in den Container schreiben und die unteren beiden Bytes ersetzen:
Aufnahmecode:

for i:=1 to length(str) do
    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.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;

Code zum Lesen:

for i:=1 to MsgSize do
    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);
    end;

Nun, für die ganz Faulen – Link zum Programm und seinem Quellcode.

Vielen Dank.

Source: habr.com

Kommentar hinzufügen