Python und Steganographie

Vor nicht allzu langer Zeit fand an meiner Schule ein Pilot- Hackathon für Schüler statt. Das Thema Aufgaben betraf die Informationssicherheit einschließlich der Datenverschlüsselung.



Eine der farbenfrohsten Aufgaben war TASK-10: Steganographie .
Wir geben eine Definition.
Steganographie ist eine Möglichkeit, Informationen zu übertragen oder zu speichern, wobei die Vertraulichkeit der Tatsache einer solchen Übertragung (Speicherung) berücksichtigt wird.
Mit anderen Worten, wenn die Kryptographie die Informationen selbst verbirgt, verbirgt die Steganographie die Tatsache ihrer Übertragung.



Leider haben das Team und ich es nicht geschafft, diese Aufgabe rechtzeitig zu erledigen, und ich habe beschlossen, sie nach der Veranstaltung abzuschließen.

Die naheliegendste Lösung zu dieser Zeit schien zu sein:

  1. Konvertieren Sie Chiffretext in Bitmengen.
  2. Machen Sie dasselbe mit dem Bild.
  3. Platzieren Sie den Text an einer zufälligen Stelle auf dem Bild und speichern Sie ihn als Bild.

Hier ist ein kleiner Code zum Konvertieren von Text in Bitmengen und umgekehrt.

def text_to_binary(event): return [int(format(ord(elem),'b')) for elem in event] def binary_to_text(event): return [chr(int(str(elem),2)) for elem in event] 

Nachdem ich meinen erfahreneren Kollegen von meinen Gedanken erzählt hatte, wurde ich geschickt, um Material zu unterrichten.
Sie müssen damit beginnen, dass die Bytes der Bilddatei nicht direkt bearbeitet werden können, wenn es sich nicht um bmp handelt.

{% - Zufallscodierer%}
Nachdem ich ein wenig über Farbmodelle gelesen hatte, entschied ich mich, die Zerlegung des Bildes auf 1 und 0 zugunsten von Änderungen der Pixel selbst in der RGB-Palette aufzugeben. Für diese Manipulationen habe ich die Kissenbibliothek ausgewählt. Hier ist ein guter Artikel darüber.

Wir haben also ein Bild. Das Bild hat Pixel. Pixel werden aus Primärfarben gebildet - Rot, Grün und Blau.

Jede der Farben ist mit einer Zahl von 0 bis 255 codiert.



Und wir haben auch ASCII-Zeichen, die ebenfalls codiert sind.

Versuchen wir, einen Text in diesem Bild zu verschlüsseln.

Bild:




Ein bisschen Text:
C macht es einfach, sich in den Fuß zu schießen; C ++ macht es schwieriger, aber wenn Sie dies tun, bläst es Ihr ganzes Bein weg
Verbinden Sie die erforderlichen Bibliotheken.

 from PIL import Image, ImageDraw from random import randint 

Dann deklarieren wir die Funktion und fügen alle Objekte ein, die für uns nützlich sind.

 def stega_encrypt(): keys = [] img = Image.open(input("path to image: ")) draw = ImageDraw.Draw(img) width = img.size[0] height = img.size[1] pix = img.load() f = open('keys.txt','w') 

Interessanter. Die wichtigste Aufgabe besteht darin, einen Weg zu finden, mit dem Nachrichten verschlüsselt werden können. Ich habe diese Methode vorgeschlagen:

  1. Nehmen Sie ein Zeichen und übersetzen Sie es in eine ASCII-Nummer
  2. Erstellen Sie ein Tupel mit zufälligen Koordinaten
  3. Wir sammeln Grün- und Blautöne von einem Pixel an den Koordinaten
  4. Ersetzen Sie den roten Farbton durch die ASCII-Zeichennummer

 for elem in ([ord(elem) for elem in input("text here: ")]): key = (randint(1,width-10),randint(1,height-10)) g, b = pix[key][1:3] draw.point(key, (elem,g , b)) f.write(str(key)+'\n') 

Wir speichern Schlüssel und das Bild.

 print('keys were written to the keys.txt file') img.save("newimage.png", "PNG") f.close() 

Code

Wir versuchen das Skript auszuführen.

Als Ergebnis haben wir das gleiche Bild erhalten, jedoch im PNG- Format und mit einigen geänderten Pixeln.



Jetzt bleibt es irgendwie alles zu entziffern.

Wir schreiben ein Skript zur Entschlüsselung!

Wir verbinden alles, was benötigt wird.

 from PIL import Image from re import findall 

Wir deklarieren eine Entschlüsselungsfunktion sowie mehrere Objekte.

 def stega_decrypt(): a = [] keys = [] img = Image.open(input("path to image: ")) pix = img.load() f = open(input('path to keys: '),'r') y = str([line.strip() for line in f]) 

Grundlegender Entschlüsselungsalgorithmus:

 for i in range(len(findall(r'\((\d+)\,',y))): keys.append((int(findall(r'\((\d+)\,',y)[i]),int(findall(r'\,\s(\d+)\)',y)[i]))) for key in keys: a.append(pix[tuple(key)][0]) return ''.join([chr(elem) for elem in a]) 

Diese regulären Ausdrücke werden benötigt, um Tupel aus einer Textdatei zu lesen.

Die letzte Aktion besteht darin, eine verschlüsselte Nachricht auf dem Bildschirm anzuzeigen.

 print("you message: ", stega_decrypt()) 

Code

Versuchen Sie nun, unsere Nachricht zu erhalten.



Wie zum Nachweis erforderlich, funktioniert alles!

Der Hauptnachteil: die Sichtbarkeit toter Pixel im Bild bei Verschlüsselung einer großen Anzahl von Zeichen. Dieser Fehler wird jedoch durch eine hohe Auflösung perfekt korrigiert.

Referenzen:

Source: https://habr.com/ru/post/de413803/


All Articles