Es war einmal, ich schrieb meine . Und dieser Beitrag war einem sehr interessanten Problem gewidmet, nämlich der Steganographie. Natürlich kann die in diesem alten Thread vorgeschlagene Lösung nicht als Steganographie im eigentlichen Sinne des Wortes bezeichnet werden. Es ist zwar nur ein Spiel mit Dateiformaten, aber trotzdem ein ziemlich interessantes Spiel.
Heute werden wir versuchen, etwas tiefer zu graben und uns den LSB-Algorithmus ansehen. Bei Interesse könnt ihr gerne unter dem Schnitt nachlesen. (Unter reduziertem Datenverkehr: etwa ein Megabyte.)
Zunächst ist eine kurze Einführung notwendig. Jeder weiß, dass der Zweck der Kryptografie darin besteht, das Lesen geheimer Informationen unmöglich zu machen. Natürlich hat die Kryptografie ihre Anwendungen, aber es gibt einen anderen Ansatz zum Datenschutz. Wir müssen die Informationen nicht verschlüsseln, aber wir können so tun, als hätten wir sie nicht. Genau aus diesem Grund wurde die Steganographie erfunden. Wikipedia versichert uns, dass „Steganographie (vom griechischen στεγανοσ – verborgen und griechisch γραφω – ich schreibe, wörtlich „Geheimschrift“) die Wissenschaft der verborgenen Übertragung von Informationen ist, indem die Tatsache der Übertragung selbst geheim gehalten wird.“
Natürlich verbietet niemand die Kombination kryptografischer und steganografischer Methoden. Und in der Praxis ist das auch ihre Praxis, aber unsere Aufgabe besteht darin, die Grundlagen zu verstehen. Wenn Sie den Wikipedia-Artikel sorgfältig studieren, werden Sie feststellen, dass es sich um den sogenannten Container und die Nachricht handelt. Ein Container ist jede Information, die dabei hilft, unsere geheime Nachricht zu verbergen.
In unserem Fall ist der Container ein Bild im BMP-Format. Sehen wir uns zunächst die Struktur dieser Datei an. Die Datei kann bedingt in 4 Teile unterteilt werden: Dateikopf, Bildkopf, Palette und das Bild selbst. Für unsere Zwecke müssen wir nur wissen, was im Titel steht.
Die ersten beiden Bytes des Headers sind die BM-Signatur, dann enthält das Doppelwort die Dateigröße in Bytes, die nächsten 4 Bytes sind reserviert und müssen Nullen enthalten, und schließlich enthält ein weiteres Doppelwort den Offset vom Anfang der Datei zu den eigentlichen Bildbytes. In einer 24-Bit-BMP-Datei wird jedes Pixel durch drei BGR-Bytes codiert.
Nachdem wir nun wissen, wie wir zum Bild gelangen, müssen wir noch herausfinden, wie wir die benötigten Informationen dort hineinschreiben können. Hier kommt die LSB-Methode ins Spiel. Das Wesentliche der Methode ist wie folgt: Wir ersetzen die niederwertigsten Bits in den Bytes, die für die Farbkodierung verantwortlich sind. Nehmen wir an, das nächste Byte unserer geheimen Nachricht ist 11001011 und die Bytes im Bild sind ... 11101100 01001110 01111100 0101100111 ..., dann sieht die Kodierung folgendermaßen aus. Wir teilen das Byte der geheimen Nachricht in vier Zwei-Bit-Teile auf: 4, 11, 00, 10 und ersetzen die niederwertigsten Bits des Bildes durch die resultierenden Fragmente: …1111 01001100 01111110 0101100111…. Ein solcher Austausch ist für das menschliche Auge im Allgemeinen nicht erkennbar. 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 beiden niederwertigsten Bits ändern können, sondern eine beliebige Anzahl davon. Hier zeigt sich ein Muster: Je mehr Bits wir ändern, desto mehr Informationen können wir verbergen und desto mehr Rauschen entsteht dadurch im Originalbild. Als Beispiel hier zwei Bilder:


Trotz aller Bemühungen war ich nicht in der Lage, den Unterschied zwischen ihnen zu erkennen, und dennoch ist im zweiten Bild mit der beschriebenen Methode Lewis Carrolls Gedicht „The Hunting of the Snark“ versteckt. Wenn Sie bis hierher gelesen haben, sind Sie wahrscheinlich daran interessiert, mehr über die Implementierung zu erfahren. Es ist ganz einfach, aber ich möchte Sie gleich darauf hinweisen, dass alles in Delphi erledigt wird. Dafür gibt es zwei Gründe: 1. Ich denke, Delphi ist eine gute, nützliche Sprache; 2. Dieses Programm entstand im Zuge der Vorbereitung eines Kurses zu den Grundlagen der industriellen Bildverarbeitung, und die Leute, denen ich diesen Kurs beibringe, können außer Delphi nichts. Für diejenigen, die mit der Syntax nicht vertraut sind, muss eines erklärt werden: shl x ist eine bitweise Linksverschiebung um x, shr x ist eine bitweise Rechtsverschiebung um x.
Nehmen wir an, wir schreiben den im String gespeicherten Text in den Container und ersetzen die unteren beiden Bytes:
Code zur Aufnahme:
für i:=1 bis Länge(str) machen
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;
zu lesender Code:
für i:=1 bis MsgSize machen
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, und für die wirklich Faulen – .
Vielen Dank.
Source: habr.com
