Der Einsatz von Steganographie hat – wie Kryptographie – Geheimhaltung und Vertraulichkeit zum Ziel. Informationen werden so verborgen, dass ein Dritter bei Betrachtung des Trägermediums keinen Verdacht schöpft. Im Gegensatz zur Kryptographie, soll eine allfällige Drittperson gar nicht merken, dass in den Daten eine verborgenen Geheimbotschaft steckt. Zwei Beispiele:

Kryptographie
Alice schickt Bob eine mit Caesar verschlüsselte Nachricht. Eve kann mithören und erkennt sofort, dass es sich um eine verschlüsselte Nachricht handelt. Sie kennt aber den Schlüssel nicht. Die Nachricht ist also durch den Schlüssel geschützt.
Steganographie
Wenn aber Alice die Nachricht an Bob in einem belanglosen Gedicht versteckt, so meint Eve, es gehe nur um ein Gedicht. Sie kommt vielleicht gar nicht auf die Idee, das in dem Gedicht eine versteckte Botschaft stecken könnte.

# Historisch

Das Bedürfnis eine Botschaft zu verstecken existiert seit langer Zeit. So zählt das uns bereits bekannte Beispiel mit dem Sklaven, der eine Nachricht auf den rasierten Schädel tätowiert erhält und dann die Haare nachwachsen lässt, eigentlich nicht zur Kryptographie, sondern genauer zur Steganographie. (allerdings kann man die Steganographie als Untergebiet der Kryptographie anschauen).

Weitere Beispiele wären:

  • Wachstafeln, wo normalerweise die Botschaft in den Wachs geritzt wurde. Hier hatte man die geheime Botschaft unter dem Wachs ins Holz geritzt. Zur Tarnung wurde dann Wachs darüber gegossen und dort eine belangelose Nachricht hingeschrieben.
  • nicht oder schwer erkennbare Wasserzeichen in Papier oder Banknoten.
  • auch unsichtbare Tine auf Papier (z.B. mit Zitronensaft) fällt in diese Kategorie

# moderne Beispiele

Ein Beispiel wo Steganographie im Alltag eingesetzt wird, ist der sogenannte Machine Identification Code. Hierbei wird bei handelsüblichen Laser- und Tintenstrahl-Druckern ein fast nicht erkennbares Wasserzeichen, bestehend aus kleinen Punkten, aufs Papier gedruckt.

Yellow Dots: Der versteckte Code auf dem Ausdruck in Form von winzigen gelben Punkten am Beispiel eines HP Color Laserjet 3700.[1]

# In Bildern

Mit dem Computer können fast alle Datenformate manipuliert werden, um geheime Botschaften zu verstecken. Wir wollen uns anschauen, wie man in einem Bild ein anderes Bild verstecken kann.

# Least significant bit (LSB)

Wenn wir uns einen roten Pixel angucken, so hat dieser z.B. die folgende Farbe rgb(255,0,0). Die erste Zahl 255 steht für den Rotanteil. Binär dargestellt gibt das 1111 1111, also 8 Bits oder 1 Byte. So detailiert werden bei gängigen Grafikformaten die Farbkanäle abgespeichert. Wenn wir uns nun ein Byte anschauen, so ist das rechteste Bit das Least significant Bit. Für die Farbe des Pixels bedeutet das, man sieht fast keinen Unterschied, ob dieses Bit 1 oder 0 ist:

Byte des Rotkanals Dezimaler Wert Farbe
1111 1111 255 rgb(255,0,0)
1111 1110 254 rgb(254,0,0)

Würden wir aber ein anderes Bit umstellen, so wäre der Unterschied erkennbar:

Byte des Rotkanals Dezimaler Wert Farbe
1111 1111 255 rgb(255,0,0)
1111 0111 247 rgb(247,0,0)

Je weiter links das Bit steht, umso stärker ist sein Einfluss auf die Farbe:

Byte des Rotkanals Dezimaler Wert Farbe
1111 1111 255 rgb(255,0,0)
0111 1111 127 rgb(127,0,0)

# Anwendung mit Bildern

Der Trick besteht nun darin, dass man in diesem "Least significant Bit* etwas abspeichert. So könnte man z.B. das LSB des Rotkanals verwenden, um ein Schwarz-Weiss-Bild darin zu verstecken.

Normales Bild
mushroom.png
Geheimes Bild
hidden.png

Im linken Bild wird nun das letzte Bit des Rotkanals verwendet: dort wo das Geheime Bild Weiss ist, wird das letzte Bit auf 1 gesetzt. Dort wo das Bild Schwarz ist, wird das letzte Bit auf 0 gesetzt. So entsteht das unten angezeigt Bild. Diese lässt sich von Auge nicht vom Original unterscheiden, beinhaltet aber die verstecke Botschaft.

Übermitteltes Bild mit verstecker Botschaft
result.png

Nun kann aus der übermittelten Datei die versteckte Botschaft wieder extrahiert werden, indem das letzte Bit des Rotkanals geprüft wird. Die wiederhergestellte Nachricht sieht wie folgt aus:

extrahierte Nachricht
extracted.png

# mit Python programmieren

Das oben präsentierte Beispiel wurde mit den untenstehenden Python-Programmen umgesetzt. Beide Programme verwenden die Library cs20-image die in Thonny installiert werden muss.

# versteckte Nachricht einbauen

Das Programm verknüpft die beiden Dateien mushroom.png und hidden.png indem diese Pixel-weise durchlaufen sind. Für jeden Pixel wird das LSB in mushroom.png auf 0 gesetzt, falls der entsprechende Pixel in hidden.png schwarz ist, resp. auf 1 wenn er weiss ist.

import image                                # das image-Modul importieren

bild = image.FileImage('mushroom.png')      # das Bild laden
width = bild.get_width()           # die Breite des geladenen Bildes als width abspeichern
height = bild.get_height()         # die Höhe als height speichern

botschaft = image.FileImage('hidden.png')   # das zu versteckende Bild laden

resultat = bild.copy()             # eine Kopie des Bildes erstellen

for row in range(height):                   # das Bild zeilenweise durchgehen – row geht von 0 bis height-1
    for col in range(width):                # die Zeile pixelweise durchgehen – col geht von 0 bis width-1
        bild_pixel = bild.get_pixel(col,row)               # den Bildpunkt an den Koordinaten (col, row) holen
        botschaft_pixel = botschaft.get_pixel(col,row)     # den Bildpunkt an den Koordinaten (col, row) holen

        botschaft_pixel_grau = (botschaft_pixel.red + botschaft_pixel.green + botschaft_pixel.blue) /3   # grauwert des zu versteckenden Pixels
        weiss = botschaft_pixel_grau > 126:                  # Umwandeln in schwarz-weiss
            
        if weiss:   
            bild_pixel.red = 2*(bild_pixel.red // 2)+1       # beim Rot-Wert das LSB auf 1 setzen    
        else:
            bild_pixel.red = 2*(bild_pixel.red // 2)         # beim Rot-Wert das LSB auf 0 setzen
            
        resultat.set_pixel(col,row,bild_pixel)       # den Bildpunkt an den Koordinaten (col, row) mit der neuen Farbe setzen

win = image.ImageWin(width, height, "Steganographie")    # ein Fenster erzeugen
resultat.draw(win)                          # das invertierte Bild im Fenster darstellen
resultat.save('result.png')                 # das invertierte Bild speichern
win.exit_on_click()                         # beim nächsten Mausklick aufs Fenster dieses schliessen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# versteckte Nachricht extrahieren

Beim Extrahieren der verstecken Nachricht wird das Bild Pixel um Pixel durchlaufen. Wenn der Rotanteil eines Pixels eine ungerade Zahl ist, dann ist das LSB gesetzt und der Bildpunkt der versteckten Nachricht wird auf Weiss gesetzt. Im anderen Fall, wird der Pixel Schwarz dargestellt.

import image                                # das image-Modul importieren

bild = image.FileImage('result.png')        # das Bild mit der versteckten Botschaft laden
width = bild.get_width()            # die Breite des Bildes als width abspeichern
height = bild.get_height()          # die Höhe als height speichern

extrahiert = bild.copy()            # eine Kopie des Bildes erzeugen

for row in range(height):                   # das Bild zeilenweise durchgehen – row geht von 0 bis height-1
    for col in range(width):                # die Zeile pixelweise durchgehen – col geht von 0 bis width-1
        bild_pixel = bild.get_pixel(col,row)     # den Bildpunkt an den Koordinaten (col, row) holen

        weiss = bild_pixel.red % 2               # das Bild ist weiss, wenn es ungerade ist (nicht durch 2 teilbar)    

        if weiss:                                # Farben setzen für Weiss
            bild_pixel.red = 255                 
            bild_pixel.blue  = 255
            bild_pixel.green = 255
        else:                                    # Farben setzen für Schwarz
            bild_pixel.red = 0                 
            bild_pixel.blue  = 0
            bild_pixel.green = 0

        extrahiert.set_pixel(col,row,bild_pixel)       # den Bildpunkt an den Koordinaten (col, row) mit der neuen Farbe setzen

win = image.ImageWin(width, height, "Steganographie")
extrahiert.draw(win)                          # die extrahierte Botschaft im  Fenster darstellen
extrahiert.save('extracted.png')              # die extrahierte Botschaft speichern
win.exit_on_click()                           # beim nächsten Mausklick aufs Fenster dieses schliessen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# Hinweise

Das Programm liesse sich erweitern. Momentan wird nur der Rotkanal verwendet, dort nur das LSB. Dadurch können nur schwarz-weiss-Bilder eingebaut werden. Es wäre aber denkbar, mehrere Farbkanäle zu verwenden oder statt des letzten, auch das zweitletzte Bit für die geheime Botschaft zu verwenden.


  1. Florian Heise, Druckerchannel.de (opens new window), via Wikimedia Commons (opens new window) (PD) ↩︎

Letzte Änderung: 14.4.2021, 22:02:07