04.01.2013 Aufrufe

Projektgruppe STEGO: Theoretischer Teil – Formate und Algorithmen

Projektgruppe STEGO: Theoretischer Teil – Formate und Algorithmen

Projektgruppe STEGO: Theoretischer Teil – Formate und Algorithmen

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

C.v.O. Universität Oldenburg<br />

Abteilung: Parallele Systeme<br />

<strong>Projektgruppe</strong> <strong>STEGO</strong>:<br />

<strong>Theoretischer</strong> <strong>Teil</strong> <strong>–</strong><br />

<strong>Formate</strong> <strong>und</strong> <strong>Algorithmen</strong><br />

Jan Christian Busch, Rene Frerichs, Lars Herrmann,<br />

Matthias Kloppenborg, Marko Krause, Christian Kuka,<br />

Sebastian Schnell, Ralf Treu<br />

Dieses Dokument beschreibt diverse Medienformate <strong>und</strong><br />

<strong>Algorithmen</strong> im Hinblick auf das steganographische Einbetten<br />

von Geheimnachrichten in Trägermedien. Es stellt<br />

die Gr<strong>und</strong>lage für den Entwurf <strong>und</strong> die Entwicklung einer<br />

allgemeinen Softwarebibliothek für die computergestützte<br />

Steganographie dar.<br />

17. Dezember 2008


Inhaltsverzeichnis<br />

1 Einführung/Motivation 5<br />

2 Ziele des Projekts 5<br />

3 Gruppenvorstellung 6<br />

4 Untersuchte Dateiformate 7<br />

4.1 GIF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7<br />

4.2 JPEG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19<br />

4.3 PNG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30<br />

4.4 WAV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36<br />

4.5 PDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38<br />

4.6 SVG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40<br />

4.7 CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41<br />

5 Vorhandene steganographische <strong>Algorithmen</strong> 43<br />

5.1 Gr<strong>und</strong>lagen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />

5.2 Einbettung in GIF-Dateien . . . . . . . . . . . . . . . . . . . . . . . . . . 44<br />

5.2.1 GIFShuffle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44<br />

5.2.2 FriRui . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45<br />

5.2.3 Sortieren/Umsortieren . . . . . . . . . . . . . . . . . . . . . . . . . 48<br />

5.3 Einbettung in JPEG-Dateien . . . . . . . . . . . . . . . . . . . . . . . . . 48<br />

5.3.1 F5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48<br />

5.3.2 MB2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52<br />

5.3.3 Perturbed Quantization <strong>–</strong> PQ . . . . . . . . . . . . . . . . . . . . . 55<br />

5.4 Einbettung in Rastergrafiken . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />

5.4.1 BattleSteg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />

5.4.2 CPT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62<br />

5.5 Einbettung in Audio-Dateien . . . . . . . . . . . . . . . . . . . . . . . . . 63<br />

5.5.1 Echo-Hiding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63<br />

5.5.2 Phase-Coding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65<br />

5.5.3 LSB <strong>–</strong> Least Significant Bits . . . . . . . . . . . . . . . . . . . . . . 66<br />

6 Verbesserungen bestehender <strong>und</strong> neue <strong>Algorithmen</strong> 67<br />

6.1 Einbettung in Bild-Dateien . . . . . . . . . . . . . . . . . . . . . . . . . . 67<br />

6.1.1 T . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67<br />

6.2 GIF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73<br />

6.2.1 Fortgeschrittener GIFShuffle . . . . . . . . . . . . . . . . . . . . . 73<br />

6.3 Einbettung in Audio-Dateien . . . . . . . . . . . . . . . . . . . . . . . . . 74<br />

6.3.1 WPC-Audio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74<br />

6.4 Einbettung in SVG-Dateien . . . . . . . . . . . . . . . . . . . . . . . . . . 75<br />

6.4.1 SVG-Winkel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75<br />

6.5 Einbettung in PDF-Dateien . . . . . . . . . . . . . . . . . . . . . . . . . . 76<br />

3


6.5.1 PDFShuffle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76<br />

6.6 Einbettung in CSS-Dateien . . . . . . . . . . . . . . . . . . . . . . . . . . 80<br />

6.6.1 CSS-Steganographie . . . . . . . . . . . . . . . . . . . . . . . . . . 80<br />

7 Die Bibliothek libstego 81<br />

7.1 Aufbau der Bibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81<br />

7.2 Implementierungsdetails . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81<br />

Glossar 82<br />

4


1 Einführung/Motivation<br />

Die Steganographie beschäftigt sich mit der Einbettung von geheimen Nachrichten in<br />

unauffällige Trägermedien. Im Gegensatz zur Kryptographie ist hier das Ziel, dass ein<br />

eventueller Angreifer vom Informationsaustausch überhaupt nichts bemerkt. Ein weit<br />

verbreitetes Beispiel für die Anwendung der Steganographie ist das sogenannte Gefangenenproblem:<br />

Alice <strong>und</strong> Bob sitzen in getrennten Zellen in einem Gefängnis <strong>und</strong> wollen ihren Ausbruch<br />

planen. Ihre einzige Kommunikationsmöglichkeit besteht darin, sich Briefe zu schicken,<br />

die jedoch alle vom Gefängniswärter untersucht werden. Sollte dieser den Verdacht<br />

schöpfen, dass Alice <strong>und</strong> Bob einen unerlaubten Plan schmieden, so wird er die Briefe<br />

nicht weiter übermitteln <strong>und</strong> jegliche weitere Kommunikation verhindern. Bei diesem<br />

Szenario ist die Verwendung einer Geheimschrift oder -Sprache nicht möglich, da der<br />

Wärter diese sofort als solche erkennen <strong>und</strong> sich weigern würde, die Briefe zuzustellen.<br />

Der Informationsaustausch muss also nicht verschlüsselt, sondern verdeckt erfolgen. Steganographie<br />

findet also überall Anwendung, wo die Informationskanäle zwischen zwei<br />

Parteien überwacht werden <strong>und</strong> der Austausch von geheimen Nachrichten unbemerkt<br />

geschehen muss.<br />

In der heutigen Zeit sind viele Menschen von Restriktionen bezüglich des Versendens<br />

von verschlüsselten Nachrichten betroffen. In vielen Ländern ist das Verschlüsseln verboten<br />

oder die Menschen werden vom Staat zur Herausgabe der Schlüssel gezwungen.<br />

Gerade für die Einwohner solcher Länder ist es wichtig, eine Möglichkeit zu haben, geheime<br />

Nachrichten zu verschicken, ohne dass jemand außer dem Empfänger der Nachricht<br />

überhaupt von dieser Nachricht erfährt.<br />

Insbesondere die computergestützte Steganographie ist noch ein recht junges Forschungsgebiet.<br />

Im Gegensatz zur Kryptographie gibt es hier nur sehr wenige standardisierte<br />

Verfahren zur Einbettung. In vielen Fällen sind die Einbettungsalgorithmen nicht<br />

offengelegt, sondern existieren nur in Form von vorkompilierten Programmen, die sich<br />

meistens nicht auf allen Betriebssystemen <strong>und</strong> Hardwareplattformen nutzen lassen.<br />

Dies erschwert einerseits den Informationsaustausch, andererseits führt es dazu, dass<br />

die Einbettungsmethoden nicht von einer ausreichend großen Personenzahl geprüft werden<br />

<strong>und</strong> somit immer eine Unsicherheit besteht, ob die gängigen Verfahren nicht beispielsweise<br />

bereits von Geheimdiensten oder ähnlichen Organisationen gebrochen wurden.<br />

Die Entwicklung einer offenen, plattformunabhängigen Softwarebibliothek, die einerseits<br />

einige vorhandene Einbettungsalgorithmen für eine Vielzahl unterschiedlicher<br />

Trägermedien implementiert, andererseits leicht um neue <strong>Algorithmen</strong> erweitert werden<br />

kann, soll diesen Problemen entgegenwirken.<br />

2 Ziele des Projekts<br />

Die <strong>Projektgruppe</strong> ” Stego“ wird im Laufe eines Jahres vorhandene steganographische<br />

<strong>Algorithmen</strong> analysieren, wenn möglich verbessern <strong>und</strong> eine quelloffene Bibliothek ent-<br />

5


werfen <strong>und</strong> implementieren, die eine Auswahl von <strong>Algorithmen</strong> enthält.<br />

In den letzten Jahren entstand eine Vielzahl an steganographischen <strong>Algorithmen</strong> für Dateiformate,<br />

die insbesondere im ” World Wide Web“ häufig Verwendung finden. Wie so<br />

oft wurden dabei teils sehr allgemeine <strong>Algorithmen</strong> entwickelt, die sich beispielsweise auf<br />

die Sortierung von Daten in einer Datei beziehen, <strong>und</strong> teils sehr spezielle <strong>Algorithmen</strong>,<br />

die nur auf wenige oder gar einzelne Dateiformate anwendbar sind. Die Sicherheit der<br />

<strong>Algorithmen</strong> ist bei der Steganographie die wichtigste Anforderung. Es gilt, den Zielkonflikt<br />

zwischen Sicherheit <strong>und</strong> Einbettungsrate zu analysieren <strong>und</strong> potentiell sichere oder<br />

deutlich verbesserbare <strong>Algorithmen</strong> aus den vorhandenen Implementierungen herauszufiltern.<br />

Der Fokus wird auf jene <strong>Algorithmen</strong> gelegt, die auf die am häufigsten verwendeten<br />

<strong>Formate</strong> im ” World Wide Web“ anwendbar sind; in der heutigen Zeit werden mehr <strong>und</strong><br />

mehr multimediale Inhalte über das Internet verbreitet, so dass die Wahl eher auf Bild<strong>und</strong><br />

Audio-<strong>Formate</strong> fällt; darüber hinaus muss der Trend berücksichtigt werden, Dateiformate<br />

mit bestimmten Kompressionsverfahren den unkomprimierten vorzuziehen, weil<br />

<strong>–</strong> trotz immer schnellerer Internetverbindungen <strong>–</strong> jene kleineren Dateien oft verwendet<br />

werden.<br />

Die <strong>Algorithmen</strong> sollen, wenn möglich, verbessert werden, jedoch soll auch eine feste<br />

Basis an etablierten <strong>Algorithmen</strong> übernommen werden. Ergebnis soll eine in der Programmiersprache<br />

C implementierte <strong>und</strong> vollständig dokumentierte, quelloffene Bibliothek<br />

sein, mit deren Hilfe unterstützte Dateien von jedem Interessierten auf mehrere<br />

Arten mit zusätzlichen Daten angereichert werden können. Um den Funktionsumfang<br />

präsentieren zu können, wird neben der Dokumentation weiterhin ein Programm mit<br />

grafischer Oberfläche entwickelt, das die Möglichkeiten der Bibliothek aufzeigen wird.<br />

Beide Programme werden zunächst von der <strong>Projektgruppe</strong> ingeneurmäßig entworfen<br />

<strong>und</strong> anschließend implementiert <strong>und</strong> werden mit Programmcode <strong>und</strong> Dokumentation<br />

bereitgestellt, um die Nutzung <strong>und</strong> weitere Forschung zu ermöglichen.<br />

3 Gruppenvorstellung<br />

Die <strong>Projektgruppe</strong> Stego setzt sich aus den folgenden Studenten der Carl-von-Ossietzky-<br />

Universität zusammen:<br />

Jan Christian Busch Student an der Carl-von-Ossietzky-Universität seit 2004 mit<br />

Schwerpunkt Informationssysteme <strong>und</strong> Software-Engineering.<br />

Aufgabe . . . GUI-Entwicklung.<br />

Rene Frerichs Student an der Carl-von-Ossietzky-Universität seit 2004 mit Anwendungsfach<br />

Musik.<br />

Aufgabe . . . Sonstige Aufgaben.<br />

Lars Herrmann Student an der Carl-von-Ossietzky-Universität seit 2003 mit Anwendungsfach<br />

Physik.<br />

6


Aufgabe . . . Server Administration.<br />

Matthias Kloppenborg Student an der Carl-von-Ossietzky-Universität seit 2004 mit<br />

Schwerpunkt eLearning/Wissensmanagement.<br />

Aufgabe . . . Quelltext Dokumentation.<br />

Marko Krause Student an der Carl-von-Ossietzky-Universität seit 2003 mit Anwendungsfach<br />

Physik.<br />

Aufgabe . . . Server-Administration.<br />

Christian Kuka Student an der Carl-von-Ossietzky-Universität seit 2006 mit Schwerpunkt<br />

Informationssysteme <strong>und</strong> Software-Engineering.<br />

Aufgabe . . . Webserver-Administration.<br />

Sebastian Schnell Student an der Carl-von-Ossietzky-Universität seit 2004 mit Anwendungsfach<br />

Physik.<br />

Aufgabe . . . Dokumentation.<br />

Ralf Treu Student an der Carl-von-Ossietzky-Universität seit 2004 mit Schwerpunkt<br />

eLearning/Wissensmanagement.<br />

Aufgabe . . . Projektleiter.<br />

4 Untersuchte Dateiformate<br />

Um computergestützte Steganographie anzuwenden ist es notwendig, den genauen Aufbau<br />

der Datenformate zu kennen, in die Geheimnachrichten eingebettet werden sollen. Im<br />

folgenden werden Medien- <strong>und</strong> Datenformate beschrieben, die sich für steganographische<br />

Einbettungen eignen. Einige der <strong>Formate</strong> werden bereits von vorhandenen steganographischen<br />

<strong>Algorithmen</strong> verwendet, andere <strong>–</strong> wie das PDF- oder CSS-Format <strong>–</strong> werden für<br />

neue, von der <strong>Projektgruppe</strong> entwickelte <strong>Algorithmen</strong>, benötitgt.<br />

4.1 GIF<br />

Zusammenfassung Das GIF (Graphics Interchange Format) ist ein palettenbasiertes<br />

Bildformat. Es bietet die Möglichkeit der Animation <strong>und</strong> es ist möglich Pixel transparent<br />

erscheinen zu lassen. Der zur Kompression der Bilddaten verwendete Algorhmus ist,<br />

anders als zum Beispiel bei JPEG, nicht verlustbehaftet.<br />

Geschichtlicher Hintergr<strong>und</strong> CompuServe präsentierte im Jahre 1987 das GIF als freie<br />

<strong>und</strong> offene Spezifikation. Nicht nur der gute Algorithmus zur Komprimierung ließen das<br />

GIF zu einem beliebten Format im Internet werden. Die Fähigkeit, das auf Seite 12 beschriebene<br />

Zeilensprungverfahren anwenden zu können, bei dem aus Sicht des Benutzers<br />

Bilder schneller aufgebaut werden können, indem beispielsweise zunächst nur jede vierte,<br />

7


dann jede zweite Zeile angezeigt wird, trug ebenfalls dazu bei. Auch die Übertragung<br />

von Farbbildern war zur damaligen Zeit nicht Standard. Die Spezifikation 89a erweiterte<br />

die Funktionen des <strong>Formate</strong>s, so dass nun auch Transparenzeffekte <strong>und</strong> Animationen<br />

verwendet werden konnten. Als CompuServe das GIF <strong>und</strong> damit auch die Spezifikation<br />

87a präsentierte, fiel zunächst niemandem auf, dass der zur Komprimierung eingesetzte<br />

LZW-Algorithmus lizenzrechtlich bedenklich war. Der LZW-Algorithmus verwendete<br />

Prozeduren, die sowohl Unisys als auch IBM im Vorfeld patentiert worden waren. Im<br />

Dezember des Jahres 2004 gaben Unisys <strong>und</strong> CompuServe bekannt, dass Entwickler,<br />

die weiterhin mit den von Unisys patentierten Technologien, welche im Zusammenhang<br />

mit dem GIF-Format stehen, arbeiten wollten, von nun an Lizenzgebühren zu zahlen<br />

hätten. Diese Gebühren, die zu Beginn nur für kommerzielle Software zu zahlen waren,<br />

wurden kurz darauf auch auf kostenlose Software ausgeweitet. Dies war ein zu erwartender<br />

Schritt von Unisys, da die kommerziellen Hersteller nach Einführung der Gebühren<br />

<strong>Teil</strong>e ihrer eigenen Software, die der Erstellung von GIF-Dateien dienten, als kostenlose<br />

Erweiterungen zur Verfügung stellten. Verwirrung entstand, da im Internet das Gerücht<br />

verbreitet wurde, dass sowohl für Programme zum Erstellen als auch für Programme<br />

zum Anzeigen von GIF-Dateien Gebühren zu entrichten wären. Dies führte letztlich<br />

dazu, dass CompuServe die Planung von GIF24 als freie, offene <strong>und</strong> gebührenfreie Spezifikation<br />

unterstützte.Dies konnte später bei der Entwicklung von PNG verwendet werden.<br />

Tatsache ist jedoch, dass Programme, welche GIF-Dateien nur auslesen, nicht von<br />

der Gebührenpflicht betroffen waren([GIFa] [GIFb]). Trotz der Entwicklung von PNG<br />

<strong>und</strong> JPEG finden GIF-Dateien noch heute Verwendung im Internet <strong>und</strong> sind durch ihre<br />

Fähigkeit zur Animation <strong>und</strong> Transparenz beliebt.<br />

Der Aufbau einer Datei nach GIF-Spezifikation 89a Der Aufbau einer GIF-Datei<br />

nach Spezifikation 89a ([GIFc]) lässt sich anhand einer einfachen Grammatik darstellen.<br />

Die mit < <strong>und</strong> > geklammerten Begriffe sind Nichtterminale. Die mit [ <strong>und</strong> ] geklammerten<br />

Begriffe sind optional. Das * bedeutet, dass der davor stehende Block mehrfach<br />

vorkommen kann. Sind Begriffe durch | getrennt, so ist dies als Exklusiv-Oder zu verstehen.<br />

Ungeklammerte Begriffe sind Terminale <strong>und</strong> werden im Folgenden erläutert.<br />

:= HeaderGIF-Endsymbol<br />

:= Bildschirmbeschreibung [globale Farbpalette]<br />

:= |<br />

:= [Erweiterung zur Grafikkontrolle]<br />

:= |<br />

Erweiterung zur Darstellung von ASCII Text<br />

:= Bildbeschreibung [lokale Farbpalette] Rasterdaten<br />

:= Erweiterung für Anwendungen |<br />

Erweiterung für Kommentare<br />

Der Header Anhand des sechs Byte großen Headers, kann man die GIF-Datei als<br />

solche erkennen: In den ersten drei Bytes ist die sogenannte Signatur gespeichert,<br />

8


durch die man erkennt, dass die folgenden Daten eine GIF-Datei beschreiben. Die<br />

Versionsnummer beschreibt die Spezifikation, anhand derer die Datei erstellt wurde. Es<br />

gibt zwei verschiedene Spezifikationen: 87a <strong>und</strong> 89a. Neuerungen in der Spezifikation<br />

89a sind z. B. der Farbwert für Transparenz, die Fähigkeit der Animation <strong>und</strong> die<br />

Möglichkeit zur Darstellung von ASCII-Text.<br />

Der Aufbau des Headers<br />

• 001011112 �= ASCII g<br />

• 001100012 �= ASCII i<br />

• 001011102 �= ASCII f<br />

• 001110002 �= ASCII 8<br />

• 001110012 �= ASCII 9<br />

• 011000012 �= ASCII a<br />

Die Bildschirmbeschreibung Die Bildschirmbeschreibung enthält die globalen Parameter<br />

für alle enthaltenen Rasterbilder, so zum Beispiel die Dimensionen des logischen<br />

Bildschirms, der zur Darstellung genutzt wird, Informationen über die zu verwendenden<br />

Farbpaletten, die Hintergr<strong>und</strong>farbe des logischen Bildschirms <strong>und</strong> die Farbtiefe. Aus<br />

den ersten vier Bytes lassen sich Höhe <strong>und</strong> Breite des logischen Bildschirms auslesen.<br />

Das anschließende Byte muss bitweise interpretiert werden:<br />

Ist das erste Bit auf Eins gesetzt so existiert eine globale Farbpalette <strong>und</strong> diese<br />

folgt auf die Bildschirmbeschreibung. Bei einem Wert von Null existiert diese Farbpalette<br />

nicht. Implementierungsabhängig können auch für jedes Rasterbild eigene sogenannte<br />

lokale Farbpaletten oder eine im Speicher vorliegende Farbpalette verwendet werden.<br />

Die folgenden drei Bits zeigen an, wie viele Bits pro Primärfarbe im Originalbild<br />

zur Verfügung standen. Zu dem gespeicherten Wert addiert man eins hinzu, um den<br />

korrekten Wert zu erhalten. Speichern diese Bits beispielsweise den Dezimalwert drei,<br />

so standen im Originalbild vier Bits pro Primärfarbe zur Verfügung um das Bild herzustellen.<br />

Das fünfte Bit gibt an, ob die globale Farbpalette sortiert ist. Die Sortierung<br />

hängt ab von der Häufigkeit der Verwendung des Farbindexes in den Rasterdaten. Je<br />

öfter der Farbindex verwendet wird, desto eher findet man den Wert in der Farbpalette,<br />

wenn man diese von Null an aufsteigend durchsucht. Die letzten drei Bits zeigen an,<br />

wieviele Bits pro Pixel zur Adressierung der Farbindizes verwendet werden. Aus diesem<br />

Wert x lässt sich mit folgender Formel die Größe der Farbpalette, gemessen in Anzahl<br />

der Farben, errechnen.<br />

F arbpalette = 2 (x+1)<br />

(1)<br />

Das nächste Byte interpretiert man als Verweis auf einen Eintrag in der Farbpalette,<br />

es gibt die Hintergr<strong>und</strong>farbe des logischen Bildschirms an. Die Bildschirmbeschreibung<br />

9


endet mit einem Byte, anhand dessen Wert y man näherungsweise das Verhältnis von Pixelhöhe<br />

zu Pixelbreite im Ursprungsbild errechnen kann. Die Formel für die Berechnung<br />

der Näherung:<br />

y + 15<br />

V erhältnis = (2)<br />

64<br />

Bei einem Wert y von 255 hat die rechte Seite der Gleichung etwas den Wert 4,21, das<br />

Verhältnis von Pixelbreite zu Pixelhöhe ist also ungefähr 4:1. Ist der Wert von y mit 1<br />

angegeben, so lautet das Ergebnis 0,25. Das Verhältnis ist damit 1:4. Liest man an der<br />

Stelle ein Nullbyte ein, so gibt es keine Informationen zum Verhältnis.<br />

Aufbau der Bildschirmbeschreibung<br />

• Breite des Bildschirms in Pixeln (2 Bytes)<br />

• Höhe des Bildschirms in Pixeln (2 Bytes)<br />

• Ein Byte<br />

<strong>–</strong> Bit für globale Farbpalette (1 Bit)<br />

<strong>–</strong> Bits pro Primärfarbe im Originalbild (3 Bits)<br />

<strong>–</strong> Bit für Sortierung der Farbpalette (1 Bit)<br />

<strong>–</strong> Bits pro Pixel (3 Bits)<br />

• Farbindex für Hintergr<strong>und</strong>farbe (1 Byte)<br />

• Verhältnis von Höhe zu Breite eines Pixels (1 Byte)<br />

Die Farbpaletten Die Farben, die in einer GIF-Datei verwendet werden, werden in<br />

Farbpaletten organisiert. Es besteht sowohl die Möglichkeit eine globale Farbpalette zu<br />

beschreiben, als auch eine lokale Farbpalette für jedes einzelne Rasterbild zu definieren.<br />

Eine Farbpalette kann, egal ob lokal oder global, bis zu 256 Farben speichern. Definiert<br />

man sowohl globale als auch lokale Farbpaletten, werden die Farbeinträge der lokalen<br />

Farbpaletten verwendet. Um eine Farbe aus dem RGB-Farbraum zu beschreiben,<br />

verwendet man drei Bytes, jeweils eines pro Gr<strong>und</strong>farbe. Die Indizes der Farbpalette<br />

verweisen direkt auf einen solchen Dreierblock von Bytes. Um einen hellen Blauton zu<br />

erhalten, wie er zum Beispiel bei der Darstellung eines Himmels genutzt werden könnte,<br />

speichert man folgende Werte.<br />

Der Aufbau der Farbpaletten<br />

• Rotwert: 011010002 = 104<br />

• Grünwert: 101010112 = 171<br />

• Blauwert: 110011002 = 204<br />

10


Diese drei Werte beschreiben eine Farbe in der Farbpalette <strong>und</strong> lassen sich anschließend<br />

über einen Index adressieren. Die Größe des Index ist auf ein Byte beschränkt, wodurch<br />

die Größe der Farbpalette auf 768 Bytes begrenzt ist.<br />

Die Bildbeschreibung Die Bildbeschreibung enthält Informationen zum einzelnen<br />

Rasterbild. GIF-Dateien können mehrere Rasterbilder enthalten, die sich zu einem<br />

Gesamtbild oder einer Animation verknüpfen lassen. Jedes Rasterbild kann zur<br />

Darstellung auf eine eigene lokale Farbpalette zugreifen oder die globale Farbpalette<br />

verwenden. Das erste Byte der Bildschirmbeschreibung enthält ein Komma, das als<br />

Trennsymbol für die einzelnen Rasterbilder dient. Die folgenden vier Bytes geben die<br />

Koordinaten an, an denen mit der Darstellung des Rasterbildes begonnen wird. Dabei<br />

bezeichnen jeweils zwei Bytes den linken sowie den oberen Abstand zum Rand des<br />

in der Bildschirmbeschreibung definierten logischen Bildschirms. Die Breite sowie die<br />

Höhe des Rasterbildes werden ebenfalls mit jeweils zwei Bytes angegeben. Das letzte<br />

Byte der Bildbeschreibung ist wie folgt aufgeteilt.<br />

Das erste Bit zeigt an, ob für das Rasterbild eine eigene lokale Farbpalette definiert<br />

ist, ob also nach den Bytes der Bildbeschreibung eine Farbpalette zu erwarten ist.<br />

Der Aufbau der Farbpaletten wurde im vorherigen Abschnitt bereits beschrieben. Das<br />

zweite Bit zeigt an, wie die Rasterdaten zu interpretieren sind. Ist dieses Bit gesetzt,<br />

so sind die Rasterdaten im Zeilensprungverfahren gespeichert. Ist dies nicht der Fall,<br />

so können die Rasterdaten sequenziell ausgelesen <strong>und</strong> dargestellt werden. Das dritte<br />

Bit gibt an, ob die lokale Farbpalette sortiert ist. Die folgenden zwei Bits sind laut<br />

Spezifikation reserviert <strong>und</strong> müssen mit Null belegt werden. Die letzten drei Bits geben,<br />

genau wie zuvor in der Bildschirmbeschreibung erläutert, an, wieviele Bits pro Pixel zur<br />

Adressierung der Farbindizes verwendet werden. Außerdem lässt sich mit Formel (1),<br />

wenn vorhanden, die Größe der lokalen Farbpalette errechnen.<br />

Der Aufbau der Bildbeschreibung<br />

• Trennzeichen 001011002<br />

• Abstand, in Pixeln, zum linken Rand des logischen Bildschirms (2 Bytes)<br />

• Abstand, in Pixeln, zum oberen Rand des logischen Bildschirms (2 Bytes)<br />

• Breite des Bildes (2 Bytes)<br />

• Höhe des Bildes (2 Bytes)<br />

• (Ein Byte)<br />

<strong>–</strong> Bit für lokale Farbpalette (1 Bit)<br />

<strong>–</strong> Bit für Zeilensprungverfahren (1 Bit)<br />

11


<strong>–</strong> Bit für Sortierung (1 Bit)<br />

<strong>–</strong> Reserviert mit Null (2 Bits)<br />

<strong>–</strong> Bits pro Pixel (3 Bits)<br />

Das Zeilensprungverfahren im GIF Bei dieser speziellen Anwendung des Verfahrens<br />

wird zunächst nur jede achte, dann jede vierte, anschließend jede zweite Zeile <strong>und</strong> letztendlich<br />

die verbliebenen Zeilen in den Rasterdaten gespeichert. Beim Auslesen werden<br />

diese dann jeweils in acht-, vier-, zwei- <strong>und</strong> einfacher Höhe dargestellt,siehe Abbildung<br />

auf Seite 12. Dies ermöglicht einen schnellen Bildaufbau, der Betrachter erhält zu Beginn<br />

eine grobe Übersicht des Bildes, deren Auflösung sich stets verdoppelt, bis das Rasterbild<br />

vollends aufgebaut ist.<br />

111111 111111 111111 111111<br />

111111 111111 111111 222222<br />

111111 111111 333333 333333<br />

111111 111111 333333 444444<br />

111111 555555 555555 555555<br />

111111 555555 555555 666666<br />

111111 1. 555555 2. 777777 3. 777777<br />

111111 → 555555 → 777777 → 888888<br />

999999 999999 999999 999999<br />

999999 999999 999999 aaaaaa<br />

999999 999999 bbbbbb bbbbbb<br />

999999 999999 bbbbbb cccccc<br />

999999 dddddd dddddd dddddd<br />

999999 dddddd dddddd eeeeee<br />

999999 dddddd ffffff ffffff<br />

Abbildung 1: Zu Beginn werden die Zeilen 1 <strong>und</strong> 9 in 8-facher Größe angezeigt. Im<br />

nächsten Schritt werden die Zeilen 5 <strong>und</strong> d ebenfalls in die Anzeige aufgenommen<br />

<strong>und</strong> alle Zeilen in 4-facher Größe dargestellt. In den folgenden<br />

Schritten wird dementsprechend weiter verfahren.<br />

Die Rasterdaten Nachdem die Rahmendaten für das Rasterbild festgelegt sind, folgt<br />

die Beschreibung der eigentlichen Bilddaten. Zu Beginn der Rasterdaten steht ein Byte,<br />

das die Anzahl an Bits pro Codewort ausgibt. Arbeitet man mit nur 17 Farben, so würde<br />

dieses Byte mit 00000101 initialisiert, da fünf Bits zur Darstellung benötigt würden,<br />

bei 70 Farben wäre der Wert also 00000111. Das nächste Byte beschreibt, wieviele<br />

Bytes in dem folgenden Datenblock übertragen werden. An diesem Punkt müsste man<br />

zeilenweise, von oben beginnend, für jedes Pixel einen Verweis auf eine Farbe aus der<br />

Farbpalette speichern. Da dies jedoch zu einer recht großen GIF-Datei führen würde,<br />

12


werden die Rasterdaten mit dem Lempel-Ziv-Welch-Algorithmus komprimiert. Dieser<br />

Algorithmus dient der Mustererkennung, so dass nicht für jedes Pixel ein Byte übertragen<br />

werden muss. Für die erkannten Muster generiert der Lempel-Ziv-Welch-Kodierer<br />

eine Codetabelle. Reicht die Anzahl an Bits, die zur Übertragung genutzt werden dürfen,<br />

nicht mehr aus, so wird ein weiteres Bit hinzugenommen. Dies lässt sich, wie später<br />

erläutert wird, leicht in den Dekodierungsvorgang einbauen. Die unkomprimierten<br />

Rasterdaten werden auf die so erzeugte Codetabelle abgebildet, <strong>und</strong> die erzeugte Folge<br />

von Codewörtern ersetzt die unkomprimierten Rasterdaten im GIF. Das Besondere am<br />

Lempel-Ziv-Welch-Algorithmus ist, dass die Codetabelle nicht <strong>Teil</strong> der GIF-Datei ist,<br />

sondern vom Decodierer aus den komprimierten Rasterdaten erstellt werden kann. Die<br />

Anzahl an Bits, die für einen Verweis in diese Codetabelle zu Beginn benötigt werden,<br />

kann, wie bereits erwähnt, aus dem ersten Byte der Rasterdaten ausgelesen werden. Die<br />

Anzahl an Bits pro Codewort zu Beginn ist abhängig von der Größe der zugeordneten<br />

Farbpalette. Die komprimierten Rasterdaten, welche jetzt bitweise vorliegen, werden zu<br />

Byte-Ketten verb<strong>und</strong>en <strong>und</strong> können dann als Datenblock gespeichert werden. Nachdem<br />

klar ist, wie groß ein Codewort ist <strong>und</strong> wie viele Bytes sich in einem Datenblock<br />

befinden, können die LZW-komprimierten Datenbytes übertragen werden. Am Ende<br />

der Rasterdaten steht als Endzeichen ein Nullbyte.<br />

Der Aufbau der Rasterdaten<br />

• Anzahl an Bits pro Codewort (1 Byte)<br />

• Anzahl an Bytes im folgenden Datenblock (1 Byte)<br />

• Datenblock<br />

Ist ein Datenblock verarbeitet, so gibt es zwei Möglichkeiten:<br />

0. Es folgt ein weiterer Datenblock, dem wieder ein Byte zur Beschreibung der Länge<br />

des Datenblocks voransteht.<br />

1. Es folgt das Endzeichen für Rasterdaten (000000002)<br />

Der Erweiterungsblock Die Unterschiede zwischen der Spezifikation 87a <strong>und</strong> 89a sind<br />

nicht gravierend. Es finden sich jedoch in der Spezifikation 89a konkrete Implementierungen<br />

des in der Spezifikation 87a vorgestellten Erweiterungsblockes.<br />

Implementierte Erweiterungen sind:<br />

• Erweiterung für Grafikkontrolle (vor Bildbeschreibung)<br />

• Erweiterung für Kommentare<br />

• Erweiterung für ASCII-Text<br />

• Erweiterung für Anwendungen<br />

13


Erweiterung für Grafikkontrolle Der Erweiterungsblock für die Grafikkontrolle<br />

ermöglicht zum Beispiel das Erstellen von Animationen. Das erste Byte enthält, wie bei<br />

jeder Erweiterung, die Bits zur Darstellung eines Ausrufezeichens. Um die Erweiterung<br />

als Grafikkontrolle zu identifizieren, enthält das nächste Byte den Dezimalwert 249.<br />

Das dritte Byte beschreibt die Anzahl an Bytes bis zum Endzeichen. Das folgende Byte<br />

betrachtet man bitweise:<br />

Laut Spezifikation sind die ersten drei Bits reserviert <strong>und</strong> standardmäßig mit<br />

Null zu belegen. Die folgenden drei Bits zeigen an, wie mit dem folgenden Rasterbild,<br />

beziehungsweise mit dem folgenden ASCII-Text-Erweiterungsblock, zu verfahren ist,<br />

nachdem die Anzeige stattgef<strong>und</strong>en hat. Die vordefinierten Werte <strong>und</strong> ihre Bedeutung<br />

werden im Folgenden dargestellt. Nachdem der folgende Block ausgelesen <strong>und</strong> angezeigt<br />

wurde,<br />

0. muss der Decoder nicht reagieren.<br />

1. wird die Anzeige belassen wie sie ist.<br />

2. werden die Pixel des logischen Bildschirms, die zur Anzeige benutzt wurden, wieder<br />

auf die Hintergr<strong>und</strong>farbe gesetzt.<br />

3. werden die Pixel des logischen Bildschirms, die zur Anzeige benutzt wurden, auf<br />

den Wert vor der Anzeige des Blocks gesetzt.<br />

Die übrigen Belegungen der drei Bits sind nicht definiert. Das folgende Bit zeigt an,<br />

ob während der Anzeige des Bildes eine Eingabe durch den Nutzer erwartet wird.<br />

Wie diese Eingabe durchgeführt wird, ist abhängig von der Implementierung des<br />

Anwendungsprogramms, das mit den GIF-Dateien arbeitet. Ist dieses Bit gesetzt,<br />

so wartet das Programm bis zum Ablauf der Verzögerungszeit auf Eingaben vom<br />

Benutzer <strong>und</strong> fährt danach mit der Verarbeitung weiterer Datenblöcke der GIF-Datei<br />

fort. Die Empfehlung von CompuServe ist, dass wenn dieses Bit gesetzt ist, auch eine<br />

Verzögerungszeit angegeben wird. Das letzte Bit gibt an, ob im Grafikkontrollblock der<br />

Index für die Transparenz gesetzt ist.<br />

Im fünften <strong>und</strong> sechsten Byte ist der Wert für die Verzögerungszeit gespeichert.<br />

Der enthaltene Wert beschreibt die Verzögerungszeit in H<strong>und</strong>ertstel einer Sek<strong>und</strong>e. Ist<br />

das Bit für Eingaben durch den Benutzer nicht gesetzt, so wartet die Anwendung für<br />

die Dauer der Verzögerungszeit, bevor sie mit der Verarbeitung der folgenden Blöcke<br />

beginnt. Das vorletzte Byte der Erweiterung zur Grafikkontrolle gibt den Index des<br />

transparenten Farbwertes an. Der Abschluss des Erweiterungsblockes ist am letzten<br />

Byte zu erkennen, welches den Wert Null speichert.<br />

Der Aufbau der Erweiterung zur Grafikkontrolle<br />

• Allgemeines Startsymbol für Erweiterungen (001000012)<br />

14


• Symbol zur Identifizierung als Erweiterung zur Grafikkontrolle (111110012)<br />

• Anzahl an Bytes bis zum Endzeichen (000001002)<br />

• (Ein Byte)<br />

<strong>–</strong> Reserviert mit Null (3 Bits)<br />

<strong>–</strong> Verfahren nach Anzeige (3 Bits)<br />

<strong>–</strong> Nutzereingaben (1 Bit)<br />

<strong>–</strong> Transparenz-Bit(1 Bit)<br />

• Verzögerungszeit (2 Bytes)<br />

• Index für die transparente Farbe (1 Byte)<br />

• Endsymbol (000000002)<br />

Erweiterung für Kommentare In dem Erweiterungsblock für Kommentare lassen sich<br />

Metainformationen zur GIF-Datei abspeichern, wie zum Beispiel eine Beschreibung des<br />

Inhaltes oder der Name des Urhebers. Die Erweiterung beginnt mit dem Startsymbol,<br />

zur Identifizierung dient wieder das zweite Byte, das den dezimalen Wert 254 speichert.<br />

Anschließend können beliebig viele Datenblöcke folgen, denen ein Byte voransteht, das<br />

die Anzahl an Bytes im Datenblock angibt.<br />

Der Aufbau der Erweiterung für Kommentare<br />

• Allgemeines Startsymbol für Erweiterungen (001000012)<br />

• Symbol zur Identifizierung als Erweiterung für Kommentare (111111102)<br />

• Anzahl an Bytes im folgenden Datenblock (1 Byte)<br />

• Datenblock<br />

• Endsymbol (000000002)<br />

Erweiterung für ASCII-Text Diese Erweiterung vereinfacht die Darstellung von Text.<br />

Da eine solche Erweiterung in der Spezifikation 87a nicht angedacht war, müssen<br />

viele Parameter in diesen Block integriert werden. Das Startsymbol ist wie bei jeder<br />

Erweiterung der dezimale Wert 33. Das identifizierende Byte speichert den Dezimalwert<br />

1. Das folgende Byte gibt die Anzahl an Bytes an, die zur Parametrisierung der<br />

eigentlichen ASCII-Daten dienen. Dieser Wert ist fest angegeben mit 12 Bytes. Die<br />

nächsten Bytes beschreiben die Maße des Gitters, in dem der Text dargestellt wird,<br />

linker <strong>und</strong> rechter Abstand zum Rand des logischen Bildschirms (jeweils zwei Bytes),<br />

sowie Breite <strong>und</strong> Höhe des Gitters in Pixeln (jeweils zwei Bytes). Um herausfinden zu<br />

können, wieviel Text gespeichert werden kann, benötigt man noch Breite <strong>und</strong> Höhe<br />

15


der Buchstaben (jeweils 1 Byte). Zur Verwendung des Erweiterungsblocks für Text<br />

benötigt man eine globale Farbpalette, denn die folgenden zwei Bytes beschreiben<br />

Text- <strong>und</strong> Hintergr<strong>und</strong>farbe <strong>und</strong> enthalten Verweise auf Einträge in der globalen<br />

Farbpalette. Nachdem alle Parameter angegeben sind, folgen die Datenblöcke mit den<br />

eigentlichen ASCII-Kodierungen, denen jeweils ein Byte vorangeht, welches die Länge<br />

des Datenblocks angibt. Das Nullbyte beendet auch diese Erweiterung.<br />

Der Aufbau der Erweiterung für ASCII-Text<br />

• Allgemeines Startsymbol für Erweiterungen (001000012)<br />

• Symbol zur Identifizierung als Erweiterung zur Darstellung von ASCII-Text<br />

(000000012)<br />

• Anzahl an Bytes der zur Darstellung benötigten Parameter (000011002)<br />

• Linker Startpunkt des Gitters, in dem der Text dargestellt wird (2 Bytes)<br />

• Oberer Startpunkt des Gitters, in dem der Text dargestellt wird (2 Bytes)<br />

• Breite des Gitters, in dem der Text dargestellt wird (2 Bytes)<br />

• Höhe des Giters, in dem der Text dargestellt wird (2 Bytes)<br />

• Breite eines Buchstabens (1 Byte)<br />

• Höhe eines Buchstabens (1 Byte)<br />

• Textfarbe (1 Byte)<br />

• Hintergr<strong>und</strong>farbe (1 Byte)<br />

• Anzahl an Bytes im folgenden Datenblock (1 Byte)<br />

• Datenblock<br />

• Endsymbol (000000002)<br />

Erweiterung für Anwendungen Die Erweiterungen für Anwendungen dienen zum<br />

Beispiel der Darstellung von sich stets wiederholenden, animierten Bildern, wie sie oft<br />

im Internet zu finden sind. Das erste Byte beschreibt das allgemeine Startsymbol für<br />

Erweiterungen. Durch den Wert des folgenden Bytes, Dezimalwert 255, ist die Erweiterung<br />

für Anwendungen zu erkennen. Die nächsten acht Bytes speichern ASCII-codierte<br />

Buchstaben, die sich zur Ausgabe in den Programmen verwenden lassen. Anhand eines<br />

Algorithmus können die Anwendungen einen 24-stelligen Binärschlüssel generieren,<br />

anhand dessen sich das Programm authentifizieren lässt. Dieser ist in den folgenden drei<br />

Bytes enthalten. Es folgen die Blöcke mit den eigentlichen Anwendungsdaten, denen<br />

jeweils ein Byte vorangeht, das die Länge des Datenblocks beschreibt. Letztendlich folgt<br />

das Nullbyte.<br />

16


Aufbau der Erweiterung für Anwendungen<br />

• Allgemeines Startsymbol für Erweiterungen 001000012<br />

• Symbol zur Identifizierung als Erweiterungsblock für Anwendungen 111111112<br />

• Anzahl an Bytes der für die Anwendung benötigten Parameter 000010112<br />

• Bytes zur Identifizierung der Anwendung 8 Bytes<br />

• Bytes zur Authentifikation der Anwendung 3 Bytes<br />

• Anzahl an Bytes im folgenden Datenblock 1 Byte<br />

• Datenblock<br />

• Endsymbol 000000002<br />

Der Lempel-Ziv-Welch-Algorithmus zur Kompression Der LZW-Algorithmus wurde<br />

1984 von Terry A. Welch in der Arbeit ” A technique for high-performance data compression”<br />

vorgestellt, [Ter84]. Ein Nachteil des Algorithmus ist allerdings, dass die Symbole<br />

immer so groß sind wie der Tabellenindex. Das bedeutet, dass nicht codierte Symbole<br />

mehr Bits benötigen als ursprünglich. Der Algorithmus ist einfach <strong>und</strong> gut dokumentiert<br />

<strong>und</strong> wird nicht nur im GIF, sondern auch in der TIFF-Spezifikation sowie in verschiedenen<br />

Komprimierungsprogrammen erwähnt.<br />

Der Algorithmus, funktioniert beim erstellen von GIF-Dateien wie folgt:<br />

Wir nehmen an, es existiere eine Farbpalette, deren enthaltene Farben mit den<br />

Indizes Null <strong>und</strong> Eins angesprochen werden können. Die Codetabelle wird zu Beginn<br />

mit den Werten für die Indizes gefüllt. Zusätzlich erstellt man zwei neue Einträge. Zum<br />

einen einen Code, mit dem die Codetabelle gelöscht werden kann, zum anderen einen<br />

Code, der das Ende der LZW-Daten markiert. Diese Codetabelle füllt man weiter mit<br />

Mustern, die man beim Einlesen der Farbwerte für ein Rasterbild erhält. Dazu liest man<br />

die Rasterdaten ein <strong>und</strong> versucht, die gelesenen Werte durch Zeichen in der Codetabelle<br />

zu ersetzen. Findet man ein Muster aus dem Eingabestrom in der Symboltabelle, so<br />

schreibt man den zugehörigen Code in die komprimierten Daten, <strong>und</strong> erstellt einen<br />

neuen Eintrag in der Codetabelle für dieses Muster, inklusive dem nachfolgenden<br />

Zeichen.<br />

Ein Beispiel:<br />

17


Eingabe Erkannt Ausgabe Neues Muster Neues Codewort<br />

10000101 1 10 <br />

0000101 0 00 <br />

000101 00 000 <br />

0101 0 01 <br />

101 10 101 <br />

1 1 <strong>–</strong> <strong>–</strong><br />

<strong>–</strong> <strong>–</strong> <strong>–</strong> <strong>–</strong><br />

Wie zu erkennen ist, lassen sich mit der Anzahl an Bytes, die man sonst zum Kodieren<br />

eines Zeichens braucht, mehrere Zeichen kodieren. Die Codeworte <strong>und</strong> sind<br />

definiert als ” Codetabelle löschen” <strong>und</strong> ” Ende der LZW-Daten”. Die Codetabelle zu<br />

löschen ist keine gängige Praxis, kann jedoch unter Umständen Platz sparen. Hierauf<br />

gehen wir jedoch nicht näher ein. Den komprimierten Datenstrom zu dekomprimieren<br />

erfordert etwas mehr Aufwand, was anhand der folgenden Tabelle deutlich wird.<br />

Eingabe Neues Muster Neues Codewort Ausgabe<br />

<strong>–</strong> <strong>–</strong> 1<br />

10 0<br />

00 00<br />

000 0<br />

01 10<br />

101 1<br />

<strong>–</strong> <strong>–</strong> <strong>–</strong><br />

Zu Beginn erkennt man die 1 <strong>und</strong> gibt diese aus. Als nächstes wird die 0 erkannt<br />

<strong>und</strong> ausgegeben. Man erstellt das neues Codewort , das für das Muster 10 steht,<br />

aus der letzten Ausgabe <strong>und</strong> dem gelesenen Zeichen. Das nächste Zeichen ist in der<br />

Codetabelle noch nicht zu finden. Aus dem Komprimiervorgang wird aber ersichtlich,<br />

dass das nächste Muster mit 0 beginnen muss. Die letzte Ausgabe wird in die Bildung<br />

des neuen Codewortes miteinbezogen, <strong>und</strong> somit steht das neue Codewort für das<br />

Muster 00 <strong>und</strong> wird direkt auf den Code angewandt. Ausgegeben wird 00. Anhand dieser<br />

Ausgabe wird mit der im nächsten Schritt erkannten 0 ein neues Muster gebildet. Das<br />

Codewort ist jetzt mit dem Muster 000 verb<strong>und</strong>en. Die neue Ausgabe ist 0. Das<br />

Codewort wird eingelesen <strong>und</strong> das Muster 10 in die Ausgabe geschrieben. Der erste<br />

Buchstabe des zuletzt erkannten Musters war eine 1. Die diesem Schritt vorangegangene<br />

Ausgabe war 0. Somit wird als neues Muster 01 mit dem Codewort notiert. Hier<br />

wird nicht, wie vielleicht erwartet, 010 als Muster unter beschrieben, da noch kein<br />

Muster 01 in der Codetabelle kodiert ist. Muster in der Codetabelle können, wie auch<br />

bei der Kompression, immer nur um einen Farbpaletteneintrag erweitert werden. Die<br />

nun gelesene 1 führt aufgr<strong>und</strong> der letzten Ausgabe von 10 dazu, dass als neues Muster<br />

101 mit dem Codewort gepeichert wird. Das Codewort bedeutet das Ende<br />

der LZW-Daten.<br />

18


Das Fazit zur Steganographie mit GIF Aufgr<strong>und</strong> der verlustfreien Komprimierung<br />

<strong>und</strong> der häufigen Verwendung von GIF-Dateien im Internet scheint dieses Format geeignet<br />

für steganographische Verfahren. Problematisch ist aber die Möglichkeit, dass<br />

sich Farben, deren Positionen in der Farbtabelle sich nur um Eins unterscheiden, völlig<br />

unterschiedliche RGB-Werte haben können. Dies schränkt die unauffällige Veränderung<br />

des LSBs eines Pixels ein. Die Möglichkeit, mehrere Farbtabellen definieren zu können,<br />

sollte nicht ausgenutzt werden, da dies die Größe der GIF-Dateien auffällig ansteigen<br />

ließe. Nicht definierte oder reservierte Bits <strong>und</strong> Bytes sollten ebenfalls nicht verwendet<br />

werden, da dies leicht zu entdecken wäre.<br />

4.2 JPEG<br />

Zusammenfassung JPEG bezeichnet ein standardisiertes Verfahren zur verlustbehafteten<br />

Speicherung von Fotos bzw. fotoähnlichen Bildern. Der Grad der Komprimierung<br />

<strong>und</strong> damit der Qualität kann stufenlos eingestellt werden <strong>und</strong> wird ausschließlich durch<br />

die sogenannte Quantisierungsmatrix gesteuert, dazu später mehr. JPEG macht sich bestimmte<br />

Eigenschaften des Auges zunutze, um effektiv Details zu entfernen, die ohnehin<br />

kaum oder nur schwer wahrnehmbar sind.<br />

Geschichte Die ” Joint Fotographic Experts Group“ wurde 1986 gegründet. Ihr offzieller<br />

Name lautet ” ISO/IEC JTC1 SC29 Working Group 1“. Dieses Komitee entstand aus<br />

einem Zusammenschluss von Experten der ISO <strong>und</strong> der ITU-T (früher CCITT). ISO<br />

steht für die ” International Organization for Standardization“. Die französische Bezeichnung<br />

” Comité Consultatif International Télégraphique et Téléphonique“ der CCITT<br />

wurde später durch den englischen Ausdruck ” International Telecommunication Union“,<br />

kurz ITU, ersetzt. Sowohl die ISO als auch die ITU sind Organisationen, die Standards<br />

überprüfen <strong>und</strong> entwickeln.<br />

Der 1992 von der Expertengruppe verabschiedete JPEG-Standard trägt die offizielle Bezeichnung<br />

” ISO/IEC IS 10918-1 | ITU-T Recommendation T.81“. Auf der offiziellen<br />

ISO-Homepage [ISO92a] können sich Interessierte das Papier gegen Entgelt herunterladen.<br />

Mit anderer Überschrift aber gleichem Inhalt gibt es das PDF bei der ITU aber<br />

auch kostenlos [ISO92b].<br />

Die Entwicklung des JPEG-Standards ermöglichte es, fotoähnliche Bilder mit variabler<br />

verlustbehafteter Kompression zu speichern oder zu laden. Durch den öffentlichen Zugang<br />

zur Spezifikation hatten Softwareentwickler die Möglichkeit, auch größere Bilder<br />

untereinander auszutauschen. Diese Eigenschaften waren für den Siegeszug des Standards<br />

im Internet verantwortlich. Nach seiner Entwicklung wurde es neben dem Graphics<br />

Interchange Format GIF das verbreitetste Format im Internet <strong>und</strong> ist es, trotz starker<br />

Konkurrenz durch neuere <strong>Formate</strong> wie PNG oder JPEG-2000, auch heute noch.<br />

Das JPEG-Komitee hat es während seiner ersten JPEG-Version versäumt, ein passendes<br />

Dateiformat zu definieren. Eric Hamilton, der in keinerlei Verbindung zur JPEG-Group<br />

stand, entwickelte das heutzutage gängige JFIF-Format Anfang der Neunziger. Es wurde<br />

im Hinblick auf Einfachheit entworfen, wodurch einige Fähigkeiten von JPEG ungenutzt<br />

blieben. Trotzdem haben nahezu alle JPEG-Dateien im Internet dieses Format.<br />

19


Bei JPEG-2000 wurde dieser Fehler nicht wiederholt <strong>und</strong> ein passendes ISOstandardisiertes<br />

Dateiformat namens JP2 zeitgleich veröffentlicht. Jenes unterstützt im<br />

Gegensatz zu JFIF alle im Standard vorgesehenen Möglichkeiten.<br />

Der offizielle Nachfolger mit der Bezeichnung ” ISO/IEC-Norm 15444-1:2000 | ITU-<br />

Empfehlung T.800“war eine konsequente Weiterentwicklung, die das hauptsächliche Problem<br />

des Vorgängers, nämlich Blockbildung bei hohen Kompressionsraten, durch Nutzung<br />

von Wavelet- statt Fourier-Transformationen löste. Die verantwortliche Expertengruppe<br />

rangierte unter der Bezeichnung ” ISO/IEC JTC l/SC 29/WG1“. Es existieren<br />

diverse JPEG-Derivate. JPEG-LS dient zum verlustfreien Speichern fotoähnlicher Bilder,<br />

wobei dieses Verfahren ohne die in JPEG verwendete Quantisierung auskommt, die<br />

selbst bei 100-prozentiger Qualitätstufe angewandt wird <strong>und</strong> verlustbehaftet ist. Daneben<br />

gibt es JBIG bzw. dessen Nachfolger JBIG2 für die Komprimierung von Grauwert<strong>und</strong><br />

Binärbildern, was beispielsweise für die Verwendung in Faxgeräten interessant ist.<br />

Im Videobereich existiert auf der einen Seite Motion-JPEG, kurz M-JPEG, <strong>und</strong> auf der<br />

anderen Seite das bekannte MPEG, das auf Video-DVDs verwendet wird.<br />

Aufbau des <strong>Formate</strong>s<br />

Farbmodell-Konvertierung Als erster Schritt der JPEG-Kompression findet eine Konvertierung<br />

vom Quell-Farbmodell zum YCbCr-Farbmodell statt. Als Quelle findet sich<br />

meist das auf Computern eingesetzte RGB-Modell, welches jede Farbe aus den Komponenten<br />

Rot, Grün <strong>und</strong> Blau zusammensetzt. Ein anderes gebräuchliches Format ist<br />

CMYK, welches sich aus den Gr<strong>und</strong>farben Cyan, Magenta <strong>und</strong> Gelb zusammensetzt<br />

<strong>und</strong> zumeist von Druckern verwendet wird. YCbCr teilt die Farbe auf in Luminanz Y<br />

<strong>und</strong> Chrominanz Cb bzw. Cr. Durch diese Definition kann man sich bestimmte Eigenheiten<br />

des menschlichen Auges zunutze machen: Es besitzt eine hohe Empfindlichkeit<br />

gegenüber Helligkeits-/Luminanzunterschieden. Farben, also Chrominanz, werden hingegen<br />

schlechter wahrgenommen, wobei der Farbunterschied Blau zu Gelb (Cb) wiederum<br />

besser ausgemacht werden kann als der von Rot nach Grün (Cr). Abbildung 2<br />

verdeutlicht dies: Das Original-Bild oben links wurde in Chrominanz <strong>und</strong> Luminanz<br />

aufgesplittet. Das Luminanz-Signal oben rechts erscheint sehr konturiert, während die<br />

beiden Chrominanzkanäle unten hingegen einen verschwommenen Eindruck machen. Der<br />

Cr-Kanal unten rechts wird von Menschen mit einer Rot-Grün-Schwäche meist nur als<br />

monoton graue Fläche wahrgenommen.<br />

Es bietet sich daher an, die einzelnen Kanäle mit unterschiedlicher Genauigkeit zu speichern.<br />

Dieses Vorgehen wird Chroma-Subsampling genannt. Im JPEG-Standard sind<br />

drei Varianten definiert:<br />

• YCbCr 4:4:4 Chrominanz-Auflösung identisch zur Luminanz-Auflösung.<br />

• YCbCr 4:2:2 horizontale Chrominanz-Auflösung halbiert.<br />

• YCbCr 4:2:0 horizontale <strong>und</strong> vertikale Chrominanz-Auflösung jeweils halbiert.<br />

Am verbeitetsten ist der letztgenannte FourCC-Code; weitere finden sich in [Fou08]. Bei<br />

Umwandlung von RGB nach YCbCr 4:2:0 findet eine Reduktion der Datenmenge auf die<br />

20


Abbildung 2: Chrominanz <strong>und</strong> Luminanz Kanäle: Oben links das Originalbild. Daneben<br />

der Helligkeitskanal. Darunter die beiden Chrominanzkanäle Cb <strong>und</strong> Cr.<br />

[Wik08h]<br />

21


Hälfte des ursprünglichen Wertes statt. Dies ist schon der erste verlustbehaftete Schritt<br />

der Komprimierung, der in Bildern mit ausgeprägten Farbunterschieden bei gleichmäßiger<br />

Helligkeit bereits sichtbar werden kann.<br />

Mathematisch wird die Umwandlung mittels einer Matrixmultiplikation vollzogen:<br />

⎡ ⎤ ⎡ ⎤ ⎡<br />

⎤ ⎡ ⎤<br />

Y 0 0,299 0,587 0,114 Rd<br />

⎣Cb⎦<br />

≈ ⎣128⎦<br />

+ ⎣−0,168736<br />

−0,331264 0,5 ⎦ · ⎣Gd⎦<br />

(3)<br />

Cr 128 0,5 −0,418688 −0,081312<br />

wobei [Rd, Gd, Bd] T <strong>und</strong> [Y, Cb, Cr] T die Farbvektoren darstellen, deren Komponenten<br />

sich im Intervall [0, 255] befinden. Werden die Komponenten nun ger<strong>und</strong>et, so passen sie<br />

exakt in ein Byte. JPEG sieht auch 12-Bit-Genauigkeit vor, was in der Praxis jedoch<br />

kaum Anwendung findet.<br />

Spektralanalyse Die einzelnen Kanäle werden nun getrennt voneinander komprimiert.<br />

Zunächst werden die Daten in 8×8-Pixel-Blöcke unterteilt, <strong>und</strong> für jeden Block wird eine<br />

Frequenzanalyse mittels diskreter Kosinus-Transformation, kurz DCT, durchgeführt:<br />

Fxy = 1<br />

4 CxCy<br />

7� 7�<br />

� � � �<br />

(2m + 1)xπ (2n + 1)yπ<br />

fmn cos<br />

cos<br />

, 0 ≤ x, y ≤ 7<br />

16<br />

16<br />

m=0 n=0<br />

Ck =<br />

� 1<br />

√2 wenn k = 0<br />

1 sonst<br />

Dabei beschreibt fmn den Pixelwert an der Stelle (m, n). Am Ende stehen 64<br />

DCT-Koeffizienten Fxy, die die einzelnen Frequenzanteile am Gesamtbild darstellen.<br />

Abbildung 3 visualisiert die einzelnen Frequenzanteile: Das originale Bild setzt sich aus<br />

einer Linearkombination dieser Blöcke zusammen mit den DCT-Koeffizienten als Gewichtung.<br />

Der Block oben links gibt den gleichförmigen Gr<strong>und</strong>ton des Blocks an, weshalb<br />

er als DC-Komponente bezeichnet wird. Die restlichen Koeffizienten, bezeichnet als<br />

AC, beschreiben nach unten rechts immmer feiner werdende Strukturen wie Kanten <strong>und</strong><br />

Muster.<br />

Das menschliche Auge ist empfindlich gegenüber groben Strukturen, wohingegen feine<br />

Details nicht so deutlich wahrgenommen werden. Nach unten rechts nehmen die Komponenten<br />

der DCT-Matrix in ihrer Bedeutung für den Gesamteindruck des Bildes also<br />

ab.<br />

Quantisierung Die Quantisierung zielt genau auf diesen Sachverhalt ab, indem die<br />

hochfrequenten Koeffizienten in ihrer Genauigkeit beschnitten werden. Dazu wird die<br />

DCT-Matrix F elementweise durch die Quantisierungmatrix Q geteilt <strong>und</strong> ger<strong>und</strong>et:<br />

F Q � �<br />

F (x, y)<br />

(x, y) =<br />

Q(x, y)<br />

Je größer die einzelnen Elemente in der Quantisierungsmatrix sind, desto kleiner sind also<br />

die Werte der resultierenden Matrix F Q . Wandelt man jene in ganzzahlige Werte um, so<br />

22<br />

Bd


Abbildung 3: Die Frequenzanteile, aus denen sich jeder 8×8-Pixel-Block zusammensetzt.<br />

Jeder Block stellt eine von 64 Frequenzen dar [Wik08e].<br />

erhält man einen Datenblock, dessen Entropie direkt abhängig ist von der verwendeten<br />

Matrix Q. Im Allgemeinen wird die Quantisierungsmatrix so gewählt, dass die Werte<br />

nach unten rechts größer werden, um besagter Frequenzmaskierung Rechnung zu tragen.<br />

23


Man siehe dazu folgende Beispielrechnung:<br />

⎡<br />

10 15 25 37 51 66 82<br />

⎤<br />

100<br />

⎢<br />

15<br />

⎢<br />

25<br />

⎢<br />

Q = ⎢ 37<br />

⎢ 51<br />

⎢ 66<br />

⎣ 82<br />

19<br />

28<br />

39<br />

52<br />

67<br />

83<br />

28<br />

35<br />

45<br />

58<br />

72<br />

88<br />

39<br />

45<br />

54<br />

66<br />

79<br />

94<br />

52<br />

58<br />

66<br />

76<br />

89<br />

103<br />

67<br />

72<br />

79<br />

89<br />

101<br />

114<br />

83<br />

88<br />

94<br />

103<br />

114<br />

127<br />

101 ⎥<br />

105 ⎥<br />

111 ⎥<br />

119 ⎥<br />

130 ⎥<br />

142⎦<br />

100 101<br />

⎡<br />

782,91<br />

105 111 119<br />

44,93 172,52<br />

130 142 156<br />

−35,28 −20,58 35,93 2,88<br />

⎤<br />

−3,85<br />

⎢<br />

−122,35<br />

⎢<br />

−2,99<br />

⎢<br />

F = ⎢ −7,98<br />

⎢ 3,87<br />

⎢ −3,77<br />

⎣ 1,78<br />

−75,46<br />

−32,77<br />

0,66<br />

7,07<br />

0,80<br />

3,28<br />

−7,52<br />

−57,18<br />

2,41<br />

0,56<br />

−1,46<br />

4,63<br />

55,00<br />

−30,07<br />

−21,28<br />

5,13<br />

−3,50<br />

3,27<br />

30,72<br />

1,76<br />

−31,07<br />

−2,47<br />

1,48<br />

2,39<br />

−17,73<br />

17,63<br />

−17,20<br />

−15,09<br />

4,13<br />

−2,31<br />

8,29<br />

12,23<br />

−9,68<br />

−17,70<br />

−6,32<br />

5,21<br />

1,97 ⎥<br />

−13,57 ⎥<br />

16,94 ⎥<br />

−3,76 ⎥<br />

−18,47 ⎥<br />

11,77 ⎦<br />

−1,75 0,43 −2,72 −3,05 3,95 −1,83 1,98 3,87<br />

F Q ⎡<br />

78 3 7 −1 0 1 0<br />

⎤<br />

0<br />

⎢<br />

−8<br />

⎢<br />

0<br />

⎢<br />

= ⎢ 0<br />

⎢ 0<br />

⎢ 0<br />

⎣ 0<br />

−4<br />

−1<br />

0<br />

0<br />

0<br />

0<br />

0<br />

−2<br />

0<br />

0<br />

0<br />

0<br />

1<br />

−1<br />

0<br />

0<br />

0<br />

0<br />

1<br />

0<br />

0<br />

0<br />

0<br />

0<br />

0<br />

0<br />

0<br />

0<br />

0<br />

0<br />

0<br />

0<br />

0<br />

0<br />

0<br />

0<br />

0 ⎥<br />

0 ⎥<br />

0 ⎥<br />

0 ⎥<br />

0 ⎥<br />

0⎦<br />

0 0 0 0 0 0 0 0<br />

Zick-Zack-Sortierung Vor der eigentlichen Entropiekodierung werden noch zwei andere<br />

Komprimierungstechniken angewendet. Zunächst findet eine Zick-Zack-Umsortierung<br />

aller AC-Komponenten eines Blocks statt. Abbildung 4 verdeutlicht diese Technik: Da<br />

die Werte Richtung unten rechts nahe Null sind, wird auf diese neue Reihenfolge nun<br />

eine verlustfreie Lauflängenkodierung angewandt.<br />

Die DC-Komponenten werden gesondert behandelt, indem hier eine Differenzkodierung,<br />

auch als prädiktive Kodierung bezeichnet, durchgeführt wird. Hierbei werden blockübergeifend<br />

nur die Differenzen der Koeffizienten untereinander gespeichert.<br />

Entropiekodierung Die abschließende verlustfreie Entropiekodierung profitiert direkt<br />

von der oben beschriebenen Quantisierung der DCT-Koeffizienten. Je größer die Werte<br />

in der Quantisierungsmatrix Q sind, desto niedriger ist die Entropie der ger<strong>und</strong>eten<br />

Matrix F Q . Dies wiederum hat eine höhere Kompressionsrate zur Folge. Der Kompressionsgrad<br />

wird bei JPEG also ausschließlich über die Werte in der Quantisierungsmatrix<br />

Q gesteuert.<br />

Im Standard sind zwei Verfahren vorgesehen:<br />

24


Abbildung 4: Zick-Zack-Umsortierung der AC-Koeffizienten [Bol07].<br />

• Huffman-Kodierung [Wik08c]<br />

• Arithmetische Kodierung [Wik08a]<br />

Die Arithmetische Kodierung ist hinsichtlich des Kompressionsgrades sehr effizient, erfordert<br />

aber eine hohe Rechenleistung <strong>und</strong> ist patentgeschützt. Die Huffman-Kodierung<br />

ist lizenzfrei <strong>und</strong> performant, erzielt aber schlechtere Kompressionsraten. Genau wie<br />

die im JPEG-Standard vorgesehene Möglichkeit der 12-Bit-Kanalgenauigkeit spielt die<br />

arithmetische Kodierung keine praktische Rolle; nahezu alle Dateien sind mit Huffman<br />

kodiert.<br />

Dekodierung Um aus einer JPEG-Datei wieder das ursprüngliche RGB-Bild zu gewinnen,<br />

müssen die Schritte des Komprimierungsvrogangs in umgekehrter Reihenfolge<br />

rückgängig gemacht werden. Dazu dekodiert man die Daten zunächst mit Huffman <strong>und</strong><br />

bringt alle Koeffizienten von ihrer Zick-Zack-Reihenfolge in ihre natürliche Position innerhalb<br />

der Koeffizienten-Matrix F Q . Um aus jener die DCT-Matrix F zurückzugwinnnen,<br />

multipliziert man sie anschließend elementweise mit der Quantisierungsmatrix Q,<br />

die in der JPEG-Datei immer mitgespeichert werden muss.<br />

Inverse diskrete Kosinus-Transformation Die IDCT wandelt die 64 Koeffizienten Fmn<br />

eines Blocks wieder um in die ursprünglichen Pixeldaten fxy:<br />

fxy = 1<br />

4<br />

7� 7�<br />

� � � �<br />

(2x + 1)mπ (2y + 1)nπ<br />

CmCnFmn cos<br />

cos<br />

, 0 ≤ x, y ≤ 7<br />

16<br />

16<br />

m=0 n=0<br />

Durch die Quantisierung <strong>und</strong> die damit entstandene Ungenauigkeit sind diese Pixelwerte<br />

verschieden von denen des Originalbildes. Das verlustbehaftete Ergebnis ist also nur noch<br />

eine Näherung der ursprünglichen Daten.<br />

25


Transformierung in das RGB-Modell Normalerweise findet als letzter Schritt eine Umwandlung<br />

nach RGB statt, um die Datei auf dem Bildschirm anzeigen zu können:<br />

⎡ ⎤<br />

R<br />

⎡<br />

1 0 1,402<br />

⎤ ⎡<br />

Y<br />

⎣G⎦<br />

= ⎣1<br />

−0,344136 −0,714136⎦<br />

· ⎣<br />

B 1 1,772 0<br />

′<br />

⎤<br />

P b⎦<br />

P r<br />

wobei vorher die Korrektur<br />

⎡ ⎤<br />

Y<br />

⎡ ⎤<br />

Y<br />

⎡ ⎤<br />

0<br />

⎣P<br />

b⎦<br />

= ⎣Cb⎦<br />

− ⎣128⎦<br />

P r Cr 128<br />

durchgeführt wird, entsprechend der Formel (3).<br />

JPEG-2000 JPEG-2000 ist eine konsequente Weiterentwicklung des originalen JPEG-<br />

Standards von 1992. Statt der diskreten Kosinus-Transformation werden Wavelet-<br />

Transformationen [Bra94] verwendet. Die Komplexität letzterer liegt bei O(N) im Gegensatz<br />

zu O(N log N) bei der DCT, wobei N für die Anzahl der Pixel steht. Dadurch<br />

entfällt die Notwendigkeit, das Bild in 8×8-Pixel-Blöcke zu unterteilen. Dies <strong>und</strong> der lokale<br />

Charakter der diskreten Wavelet-Transformation, kurz DWT, verhindern die bei hoher<br />

Kompressionsrate auftauchende Klötzchenbildung in JPEG-Bildern, siehe dazu Abbildung<br />

5. Beim JPEG-Bild links wird die Einteilung in grobe Blöcke sichtbar, während<br />

Abbildung 5: Vergleich von JPEG, links, zu JPEG-2000 bei 66-facher Kompressionsrate<br />

[Wik08f].<br />

das JPEG-2000-Bild rechts lediglich unscharf wird.<br />

Die zweite wichtige Neuerung betrifft die Entropie-Kompression, die ausschließlich mittels<br />

arithmetischer Kodierung durchgeführt wird.<br />

Dateiformat<br />

JPEG File Interchange Format <strong>–</strong> JFIF JFIF in seiner neuesten Version 1.02 von 1992<br />

ist das einzige bedeutende Bildformat, das den JPEG-Standard von 1992 implementiert.<br />

26


Die Endung .jpg ist die gebräuchlichste, weniger verbreitet sind .jpe, .jpeg oder .jfif. Das<br />

Farbmodell ist auf YCbCr beschränkt <strong>und</strong> die maximale Auflösung beträgt 65536×65536<br />

Pixel. Es ist keine Definition des Farbraums vorgesehen. Es wird jedoch das Seitenverhältnis,<br />

englisch: ” aspect ratio“, mitgespeichert. Der Mime-Typ lautet ” image/jpeg“.<br />

Eine progressive Speicherung der Bilddaten erlaubt es, eine grobe Bildvorschau zu erhalten,<br />

bevor die Datei, beispielsweise über eine langsame Verbindung ins Internet, komplett<br />

übertragen ist. Für eine Bildergalerie bietet JFIF außerdem die Möglichkeit, ein<br />

unkomprimiertes RGB-Vorschaubild einzubetten. Im optionalen EXIF-Bereich können<br />

Metadaten, wie beispielsweise GPS-Koordinaten, eingetragen werden.<br />

JFIF ist in Segmente aufgeteilt. Diese entsprechen dem, was in anderen <strong>Formate</strong>n als<br />

Tags bezeichnet wird. Das eigentliche Datensegment beginnt nach dem optionalen Header<br />

mit einem Start-Of-Image-Marker. Dieser SOI-Marker besteht aus den zwei Bytes<br />

0xFF <strong>und</strong> 0xD8.<br />

Ein Tag-Header besteht immer aus vier Bytes: 0xFF XX SizeUB <strong>und</strong> SizeLB. Dabei gibt<br />

XX gibt den Typ des Segments an; Tabelle 1 listet die Möglichkeiten dazu auf.<br />

Die Länge des Datensegments errechnet sich aus SizeUB · 256 + SizeLB, <strong>und</strong> enthält<br />

immer die zwei Bytes SizeUb <strong>und</strong> SizeLB selbst, womit ein leeres Datensegment die<br />

Größe von zwei Bytes hat.<br />

Der konkrete Aufbau einer JFIF-Datei sieht wie folgt aus:<br />

1. SOI-Marker: 0xFF 0xD8<br />

2. JFIF-Tag: FF E0 00 10 4A 46 49 46<br />

4A 46 49 46 ist die ASCII-Codierung für JFIF<br />

3. . . . weitere Tags<br />

• unkomprimiertes Vorschaubild (optional)<br />

• Quantisierungstabelle(n)<br />

• . . .<br />

4. SOS Start of Scan: enthält entropiekodierte Pixeldaten<br />

5. EOI End of Image<br />

JP2 JP2 ist das, im Gegensatz zu JFIF, ISO-standardisierte Dateiformat für JPEG-<br />

2000. Es wurde in <strong>Teil</strong> 1 der Spezifikation definiert [ISO00].<br />

Neben der Farbraum-Definition, nicht zu verwechseln mit dem Farbmodell, bietet es<br />

einen optionalen Transparenzkanal <strong>und</strong> die Möglichkeit, palettenbasiert zu speichern.<br />

Die Dateiendung ist festgelegt auf .jp2. Der MIME-Typ lautet ” image/jp2“.<br />

Einsatzgebiet Die JPEG-Kompression lässt sich überall dort einsetzen, wo visuelle<br />

Verluste in Kauf genommen werden können. Das Verfahren ist nicht nur auf statische<br />

Bilder beschränkt, sondern kann auch auf bewegte Bilder angewandt werden.<br />

27


FF xx Symbol Bezeichnung<br />

FF D8 SOI Start Of Image<br />

FF E0 APP0 JFIF tag<br />

FF Cn SOFn Start of Frame Marker, legt Art der Kompression fest:<br />

FF C0 SOF0 Baseline DCT<br />

FF C1 SOF1 Extended sequential DCT<br />

FF C2 SOF2 Progressive DCT<br />

FF C3 SOF3 Lossless (sequential)<br />

FF C5 SOF5 Differential sequential DCT<br />

FF C6 SOF6 Differential progressive DCT<br />

FF C7 SOF7 Differential lossless (sequential)<br />

FF C8 JPG reserviert für JPEG extensions<br />

FF C9 SOF9 Extended sequential DCT<br />

FF CA SOF10 Progressive DCT<br />

FF CB SOF11 Lossless (sequential)<br />

FF CD SOF13 Differential sequential DCT<br />

FF CE SOF14 Differential progressive DCT<br />

FF CF SOF15 Differential lossless (sequential)<br />

FF C4 DHT Definition der Huffman Tabellen<br />

FF CC DAC Definition der arithmetischen Codierung<br />

FF DB DQT Definition der Quantisierungstabellen<br />

FF E1 APP1 EXIF Daten<br />

FF EE APP14 Oft für Copyright Einträge<br />

FF En APPn n = 2 . . . F allg. Zeiger<br />

FF FE COM Kommentare<br />

FF DA SOS Start of Scan<br />

FF D9 EOI End of Image<br />

Tabelle 1: Mögliche Tag-Typen innerhalb einer JFIF-Datei [Wik08d]<br />

28


Bilder Das Format JFIF wird in vielen Bereichen der PC-Welt verwendet:<br />

• Internet-Browser<br />

• Java<br />

• Bildverarbeitungssoftware: Paint, Gimp, Photoshop . . .<br />

• Spiele<br />

Im Internet ist es neben GIF immer noch das beherrschende Format, da es aufgr<strong>und</strong> der<br />

kleinen Dateien schneller übertragen werden kann.<br />

Die Java-VM unterstützt das Speichern <strong>und</strong> Laden von JPEG-Dateien, ohne dass der<br />

Entwickler auf externe Bibliotheken angewiesen ist. Selbst Spiele, die auf DVDs ausgeliefert<br />

werden, greifen auf das platzsparende Format zurück, um Texturen zu speichern.<br />

Digitale Fotoapparate im semiprofessionellen Bereich speichern die Megapixel-Bilder<br />

im JFIF-Format, wobei gelegentlich Spezialprozessoren eingesetzt werden, die hardwaremäßige<br />

JPEG-Kompression sehr schnell durchführen können. Für Profi-Fotografen<br />

hingegen eignet sich JFIF nur bedingt, weshalb es in diesem Bereich nur sehr selten anzufinden<br />

ist. Artefaktbildung, mangelnde Kanalauflösung, die bei JFIF nur 8 Bit beträgt,<br />

<strong>und</strong> fehlende Farbraumdefinition sind hier KO-Kriterien.<br />

Video Die einfachste Möglichkeit, JPEG in Videos einzusetzen, ist Motion-JPEG, kurz<br />

M-JPEG. Hierbei werden die einzelnen Frames unabhängig voneinander mittels JPEG<br />

komprimiert <strong>und</strong> nacheinander abgespeichert. Da dieses Verfahren wenig Rechenleistung<br />

erfordert <strong>und</strong> trotzdem zufriedenstellende Qualität liefert, wird es gerne auf mobilen<br />

Geräten wie digitalen Videokameras eingesetzt. M-JPEG ist kein offiziell verabschiedeter<br />

ISO-Standard, sondern nur eine Aneinanderreihung von JFIF-Bildern, weshalb die<br />

Speicherung der zum Video gehörigen Tonspur nicht klar definiert ist.<br />

Die Position der Tonspur ist hingegen bei MPEG, das von der Expertengruppe mit der<br />

Bzeichnung ” ISO/IEC JTC1/SC29/WG11“ entwickelt wurde, im Standard verankert.<br />

Das JPEG-Kompressionsverfahren wird hier noch mit anderen Techniken kombiniert,<br />

wie beispielsweise Block-Motion-Compensation. Diese frameübergeifende Kompression<br />

ermöglicht kleinere Dateien bei gleicher Qualität, erfordert jedoch höhere Rechenleistung.<br />

MPEG wird unter anderem auf Video-DVDs <strong>und</strong> im Bereich digitaler Fernsehübertragung,<br />

Digital Video Broadcasting (DVB), eingesetzt.<br />

JPEG-2000 JPEG-2000 konnte trotz seiner Überlegenheit bis heute keine große Verbreitung<br />

erlangen. Der einzige Browser, der dieses Format nativ unterstützt, ist die Mac<br />

OS X-Version von Safari, weshalb solche Dateien im Internet auch nur selten anzutreffen<br />

sind.<br />

Dennoch gibt es Spezialanwendungen, die vom neuen Standard Gebrauch machen: der<br />

medizinische DICOM-Standard erlaubt die Einbettung von JPEG-2000 in seine Datensegmente.<br />

Die Texturen im Online-Rollenspiel ” Second Life“ werden platzsparend damit<br />

komprimiert. Neuere PC-Spiele werden diese Möglichkeit wohl auch bald nutzen. Die<br />

29


neuen deutschen Reisepässe speichern elektronisch Fingerabdrücke <strong>und</strong> Passbilder im<br />

JPEG-2000-Format.<br />

4.3 PNG<br />

Zusammenfassung PNG ist ein standardisiertes freies Bildformat, das ursprünglich<br />

als Ersatz für das GIF-Format geplant war, weil jenes den patentierten LZW-<br />

Kompressionsalgorithmus verwendet. PNG unterstützt<br />

• Palettengrafiken mit bis zu 256 Farben,<br />

• Graustufenbilder mit 1, 2, 4, 8 oder 16 Bit Graustufentiefe pro Pixel,<br />

• Rastergrafiken im Farbraum RGB mit 24 oder 48 Bit Farbtiefe pro Pixel<br />

• sowie Alphakanäle mit 8 oder 16 Bit.<br />

Dabei tritt besonders die Möglichkeit in den Vordergr<strong>und</strong>, einzelne Pixel mit 256 oder<br />

65536 Abstufungen von Transparenz darzustellen, wohingegen das GIF-Format nur<br />

volle Transparenz unterstützt.<br />

Für Animationen, für die das GIF-Format berühmt ist, wurde als spezieller Nebenzweig<br />

der Entwicklung von PNG das Format MNG (Multiple-Images Network Graphics)<br />

entwickelt, das sich aber nicht durchsetzte.<br />

PNG wird mittlerweile von allen gängigen Programmen zur Anzeige von Grafiken<br />

unterstützt, allen voran die Webbrowser. Nachzügler war hier der von Microsoft<br />

entwickelte Internet Explorer, der erst ab Release 7 PNG-Grafiken in vollem Umfang<br />

unterstützte.<br />

Kompression wird in PNG durch den Deflate-Algorithmus bereitgestellt, der sich aus<br />

dem LZ77-Algorithmus, einem Vorgänger des LZW-Algorithmus, mit dem es keine<br />

patentrechtlichen Probleme gab, <strong>und</strong> Huffman-Codes zusammensetzt. Obwohl der<br />

Kompressionsalgorithmus mit LZ77 insgesamt nicht so effizient ist wie LZW, ist die<br />

Kompression von PNG-Dateien ingesamt besser als die von GIF-Dateien, weil Vorfilter<br />

verwendet werden [MA99] [Roe].<br />

Standards, Dokumente Das PNG-Dateiformat wird zur Zeit in aktueller Version vom<br />

W3C in einer sogenannten W3C-Recommendation, also einer Empfehlung, sowie dem<br />

ISO-PNG-Standard beschrieben.<br />

Aufbau von PNG-Dateien PNG war, wie die meisten freien Projekte, von Beginn an in<br />

Hinblick auf Modularität <strong>und</strong> Übersichtlichkeit konzipiert. Nach einem Dateiheader folgt<br />

eine Reihe von sogenannten Chunks (Brocken, Stück), die von unterschiedlichen, festgelegten<br />

<strong>und</strong> frei gewählten Typen sein können <strong>und</strong> alle Daten des Bildes speichern. Dazu<br />

gehören neben den Pixeldaten oder Palettendaten selbst zum Beispiel auch Metainformationen<br />

über das Bild oder Chunks für spezielle Arten von Transparenz. Im folgenden<br />

30


werden die elementaren Chunks des <strong>Formate</strong>s vorgestellt, die für die Darstellung von<br />

PNG-Bildern notwendig sind.<br />

Aufbau des <strong>Formate</strong>s Datei-Header<br />

Der Header einer PNG-Datei enthält in den ersten acht Bytes der Datei die gr<strong>und</strong>legenden<br />

Daten, die Darstellungs- oder Bearbeitungsprogramme benötigen:<br />

Byte 1 2 3 4 5 6 7 8<br />

HEX-Darstellung 89 50 4e 47 0d 0a 1a 0a<br />

ASCII-Darstellung \211 P N G \r \n \032 \n<br />

Die einzelnen Bytes haben die folgende Bedeutung:<br />

1: Ein Startzeichen zur Identifikation des Dateiformats, da einige ältere Betriebssysteme<br />

allein anhand des ersten Bytes eine Datei identifizieren. Das Zeichen wurde<br />

absichtlich so gewählt, dass es nicht als ASCII-Zeichen interpretierbar ist, damit die<br />

Datei nicht fälschlicherweise als gewöhnliche ASCII-Textdatei interpretiert werden<br />

kann.<br />

2, 3, 4: Der Name des Dateiformats in ASCII-Codierung.<br />

5, 6: Unter den von Microsoft produzierten Betriebssystemen DOS <strong>und</strong> Windows wird<br />

für das Einleiten einer neuen Zeile neben dem Standard \n, das für Linefeed steht,<br />

auch \r verwendet. Dies simuliert die noch aus Zeiten der Schreibmaschine bekannte<br />

Folge von Linefeed <strong>und</strong> Carriage Return (genannt CR-LF-Verfahren), wobei<br />

Linefeed das Hinunterschieben des Druckkopfes auf eine neue Zeile <strong>und</strong> Carriage<br />

Return das Zurückschieben des Druckkopfes an den Begin der Zeile bezeichnet.<br />

Diese Kombination dient der Überprüfung auf Übertragungsfehler beim Transport<br />

der Daten über ein Netzwerk.<br />

7: Da das DOS-Betriebssystem von Microsoft nicht mit Dateien vom Typ PNG umgehen<br />

kann, wurde hier das DOS-Standard-Stoppzeichen eingeführt, so dass das<br />

Auslesen einer PNG-Datei an diesem Punkt abbricht.<br />

8: Wie bereits die Bytes fünf <strong>und</strong> sechs dient auch dieses Zeichen dem Integritätstest.<br />

In dieser Variante wird nur der Befehl Linefeed verwendet, der auf Unix-Systemen<br />

Standardbefehl für einen Zeilenumbruch ist.<br />

Da das PNG-Format, wie bereits erwähnt, auf Modularität ausgelegt ist, reicht es<br />

aus, im Datei-Header das Dateiformat eindeutig zu beschrieben <strong>und</strong> Integritätstests<br />

durchzuführen [MA99].<br />

31


Chunks In PNG-Grafiken werden außer dem Datei-Header alle Daten in Chunks<br />

gehalten. Hier können sowohl die eigentlichen Bilddaten wie Palette oder Pixeldaten,<br />

als auch Metainformationen in Text-Chunks oder zusätzliche Informationen wie Transparenz<br />

einzelner Pixel gespeichert werden.<br />

Aufbau von Chunks Alle Chunks haben den gleichen Aufbau: Die ersten vier Bytes<br />

geben die Länge des Chunks an, darauf folgen vier weitere Bytes, die vier ASCII-Zeichen<br />

für die Beschreibung des Typs des Chunks, anschließend die eigentlichen Daten des<br />

Chunks, die beliebig groß sein können, <strong>und</strong> zuletzt die CRC-Checksumme des Typ- <strong>und</strong><br />

des Datenfeldes. PNG verwendet eine Prüfsumme mit Cyclic Red<strong>und</strong>ancy Check mit<br />

dem standardmäßig verwendeten Polynom 32. Grades.<br />

Anzeige- oder Bearbeitungsprogramme können durch diese Konvention rasch die ersten<br />

acht Bytes auslesen, anhand des Typ-Feldes entscheiden, ob die enthaltenen Daten für<br />

die Anzeige oder Bearbeitung wichtig sein könnten, <strong>und</strong> gegebenenfalls zum nächsten<br />

Chunk springen.<br />

Eine PNG-Grafik muss immer mindestens einen Header-Chunk (IHDR), dann mindestens<br />

einen Daten-Chunk (IDAT) <strong>und</strong> letztlich einen End-Chunk (IEND) enthalten.<br />

Der Header-Chunk muss der erste Chunk nach dem eigentlichen Datei-Header sein <strong>und</strong><br />

der End-Chunk muss der letzte Chunk in der Datei sein. Für Palettengrafiken wird<br />

außerdem ein Paletten-Chunk (PLTE) benötigt. Die eigentlichen Bilddaten können<br />

in mehrere Daten-Chunks aufgeteilt sein. Die Größe dieser Chunks ist meist von den<br />

Puffergrößen der verwendeten Bildbearbeitungsprogramme abhängig.<br />

Neben den in der PNG-Spezifikation angegebenen Chunks können Chunks auch selbst<br />

definiert werden. Einige Programme zur Bildverarbeitung oder Bildindizierung verwenden<br />

diese zum Speichern zusätzlicher Informationen, die für die jeweiligen Programme<br />

wichtig sind.<br />

Namenskonventionen für Typbeschreibungen von Chunks Die Benennung von<br />

Chunks erfolgt nicht willkürlich. Die Groß- <strong>und</strong> Kleinschreibung der einzelnen Buchstaben<br />

im Typ-Feld wird durch das fünfte Bit im Byte induziert. Der Buchstabe wird<br />

groß geschrieben, wenn das Bit auf Null gesetzt ist, <strong>und</strong> klein geschrieben, wenn das Bit<br />

auf Eins gesetzt ist. Im folgenden sind die jeweils fünften Bits jedes Bytes aufgeführt:<br />

Byte 1: Ancillary Bit (Hilfsbit)<br />

• Wird der Buchstabe groß geschrieben, ist der Chunk zur Darstellung des Bildes<br />

notwendig. Programme, die diesen Chunk nicht verstehen, können demnach<br />

das Bild nicht anzeigen.<br />

• Wird der Buchstabe klein geschrieben, kann der Chunk von Bearbeitungsoder<br />

Anzeigeprogrammen ignoriert werden.<br />

Byte 2: Private Bit (privates Bit)<br />

32


• Wird der Buchstabe groß geschrieben, gehört der Chunk zu den offiziell in<br />

der PNG-Spezifikation genannten Chunks.<br />

• Wird der Buchstabe klein geschrieben, stammt er von einem Programm, das<br />

ihn zu speziellen Zwecken benutzt.<br />

Byte 3: Reserved Bit (reserviertes Bit)<br />

• Dieser Buchstabe muss zur Zeit immer groß geschrieben werden. Das Byte ist<br />

reserviert, zur Zeit gibt es aber noch keine offizielle Bedeutung dafür.<br />

Byte 4: Safe-to-copy Bit (sicher-zu-kopieren-Bit)<br />

• Wird dieser Buchstabe groß geschrieben, ist der Chunk gewissermaßen<br />

schreibgeschützt. Dies bedeutet, dass ein Programm, das den Chunk nicht<br />

versteht, ihn nicht löschen oder Änderungen daran vornehmen darf.<br />

• Wird dieser Buchstabe klein geschrieben, darf der Chunk geändert oder<br />

gelöscht werden, auch wenn das bearbeitende Programm den Chunk nicht<br />

versteht.<br />

Die PNG-Spezifikation visualisiert diese Namenskonvention anhand des Beispiels<br />

” bLOb“ [MA99]:<br />

b klein geschrieben Ancillary Bit ist 1<br />

L groß geschrieben Private Bit ist 0<br />

O groß geschrieben Reserved Bit ist 0<br />

b klein geschrieben Safe-to-copy Bit ist 1<br />

IHDR-Chunk Nachdem der eigentliche Header der Datei dazu dient, nur die elementaren<br />

Informationen über die Datei zu speichern, werden im darauf folgenden Header-<br />

Chunk die gr<strong>und</strong>legenden Informationen über das Bild genannt:<br />

• 4 Bytes speichern die Breite des Bildes.<br />

• 4 Bytes speichern die Höhe des Bildes.<br />

• 1 Byte speichert die Farbtiefe des Bildes.<br />

• 1 Byte speichert den Farbtyp.<br />

• 1 Byte speichert die Kompressionsmethode. Zur Zeit wird nur der Deflate-<br />

Algorithmus unterstützt.<br />

• 1 Byte speichert die Methode zum Vorfiltern. Vorfilter werden zur Zeit von den<br />

meisten Programmen nicht standardmäßig angeboten.<br />

• 1 Byte speichert die Interlace-Methode (Zeilensprung-Methode). Interlacing beschreibt<br />

den Bildaufbau nicht von oben links nach unten rechts, sondern beispielsweise<br />

zunächst mit jeder vierten Zeile.<br />

33


In diesem Chunk können nicht beliebige Kombinationen von Bytes gespeichert werden.<br />

Offensichtlich stehen der Farbtyp <strong>und</strong> die Farbtiefe in Korrelation, da nicht in jedem<br />

unterstützten Farbtyp alle Farbtiefen verwendet werden können. Folgende Kombinationen<br />

sind erlaubt:<br />

Farbtiefe Erlaubte Bittiefe Bedeutung<br />

0 1, 2, 4, 8, 16 Pixel beschreibt Grauwert<br />

2 8, 16 Pixel beschreibt RGB-Tripel<br />

3 1, 2, 4, 8 Pixel beschreibt Palettenindex<br />

4 8, 16 Pixel beschreibt Grauwert <strong>und</strong> Transparenzwert<br />

6 8, 16 Pixel beschreibt RGB-Tripel <strong>und</strong> Transparenzwert<br />

PLTE-Chunk Sofern im Feld für den Farbtyp gespeichert wurde, dass es sich um eine<br />

Palettengrafik handelt, muss der PLTE-Chunk im Bild genau einmal vorhanden sein,<br />

<strong>und</strong> zwar direkt nach dem IHDR-Chunk. Da jeder Chunk seine Länge selbst speichert,<br />

kann eine Farbpalette bei PNG-Grafiken zwischen 1 <strong>und</strong> 256 Farben beliebig lang sein,<br />

wobei jede Farbe durch drei Bytes, je für Rot, Grün- <strong>und</strong> Blau-Anteil, gespeichert wird.<br />

Dies ist ein Vorteil gegenüber GIF-Grafiken, bei denen eine Palette immer die Länge<br />

derjenigen Zweierpotenz hat, die mindestens alle verwendeten Farben halten kann, <strong>und</strong><br />

damit in den meisten Fällen unnötige Einträge speichert.<br />

IDAT-Chunk Eine PNG-Grafik muss immer mindestens einen IDAT-Chunk enthalten,<br />

es kann aber auch, unter der Auflage, dass alle zusammenhängen, eine beliebig lange<br />

Folge von IDAT-Chunks verwendet werden. Hier gibt meist die Puffergröße der verwendeten<br />

Bearbeitungsprogramme den Ausschlag.<br />

Die Daten in den IDAT-Chunks beschreiben die Farb- oder Graustufenwerte sowie<br />

gegebenenfalls die Transparenzwerte, wenn es sich um eine Rastergrafik handelt, oder<br />

die Palettenindizes, wenn es sich um eine Palettengrafik handelt. Der Chunk speichert<br />

nur fertig komprimierte Daten; es läuft also gegebenenfalls ein Vorfilter über die<br />

Bilddaten <strong>und</strong> anschließend komprimiert der Deflate-Algorithmus diese Daten, bevor<br />

sie in die IDAT-Chunks geschrieben werden.<br />

IEND-Chunk Ein IEND-Chunk muss als letztes Chunk jeder PNG-Grafik vorhanden<br />

sein. Es enthält außer dem Namen <strong>und</strong> einer Länge von null keine weiteren Daten. Beim<br />

Auslesen einer PNG-Grafik wird dieses Chunk lediglich verwendet, damit klar ist, dass<br />

das Bild vollständig vorliegt <strong>und</strong> keine weiteren Daten von Anzeigeprogrammen mehr<br />

ausgelesen werden müssen.<br />

Text-Chunks Zum Speichern zusätzlicher Informationen ist das System mit Chunks<br />

beliebig erweiterbar, solange es noch unbenutzte Typ-Namen für Chunks gibt. Trotzdem<br />

34


gibt es drei Arten von Text-Chunks, die zum Standard gehören <strong>und</strong> dazu vorgesehen<br />

sind, alle für Anzeigeprogramme eventuell wichtigen Metadaten zu speichern:<br />

tEXt: Dieser Chunk wird für kurzen Text verwendet, der nicht komprimiert werden<br />

muss oder soll. Die Kodierung der einzelnen Textinhalte erfolgt in Latin1 nach<br />

ISO Standard 8859-1. Das bedeutet, dass keine Buchstaben gespeichert werden, die<br />

nicht zum Standardzeichensatz gehören. Einzige Ausnahme ist das Zeilenumbruch-<br />

Zeichen. Das Datenfeld dieses Chunks speichert lediglich ein Schlüsselwort, das<br />

maximal 79 Bytes lang ist, ein Null-Byte zum Trennen <strong>und</strong> die Textnachricht.<br />

zTXt: Für den Fall, dass größere Textinhalte im Bild gespeichert werden sollen, sieht<br />

der Standard diesen Chunk vor, der neben dem Schlüsselwort <strong>und</strong> dem Text noch<br />

ein Feld für die Kompressionsmethode speichert. Laut aktuellem Standard wird<br />

zur Kompression von Text-Chunks wie auch den eigentlichen Bilddaten nur der<br />

Deflate-Algorithmus unterstützt. Damit das Schlüsselwort jedes Chunks schnell<br />

ausgelesen werden <strong>und</strong> bei Bedarf der dahinterstehende Text dekomprimiert werden<br />

kann, wird nur der Text selbst, nicht aber das maximal 79 Bytes lange<br />

Schlüsselwort komprimiert. Der Buchstabe z im Chunk-Namen steht für zlib, eine<br />

Bibliothek, die den Deflate-Algorithmus implementiert.<br />

iTXt: Dieser Chunk ermöglicht internationale Metadaten. Ein Feld speichert die nach<br />

RFC 3066 definierten Abkürzungen für menschliche Sprachen. Das Feld für das<br />

Schlüsselwort bleibt erhalten, es wird allerdings ein Feld für die Übersetzung des<br />

Schlüsselwortes mit angehängt. Des Weiteren enthält auch dieser Chunk ein Feld<br />

für die Kompressionsmethode, wobei auch hier nur der eigentliche Textteil komprimiert<br />

werden kann.<br />

Die Besonderheit des internationalen Text-Chunks ist, dass als Zeichensatz zum<br />

Speichern der Metadaten der UTF-8-Zeichensatz verwendet wird. Dies gewährleistet,<br />

dass auch Sonderzeichen aller möglichen Sprachen, wie sie im UTF-Standard<br />

in ISO/IEC 10646-1 definiert sind, gespeichert werden können.<br />

hIST-Chunk Für Palettengrafiken unterstützt das PNG-Format die Möglichkeit,<br />

ein Histogramm, also eine Statistik über die Häufigkeit des Vorkommens einzelner<br />

Paletteneinträge im Bild, zu speichern. Im Datenteil dieses hIST-Chunks wird eine<br />

Reihe von 16 Bit langen Ganzzahlen vom Typ ” unsigned int“ gespeichert, die für jeden<br />

Eintrag der Farbpalette jeweils die ungefähre Häufigkeit des Vorkommens dieser Farbe<br />

im Bild speichert. Nachdem Histogramm-Einträge stets näherungsweise erfolgen, hat<br />

nur der exakte Null-Wert eine spezielle Bedeutung, nämlich, dass die angegebene Farbe<br />

im gesamten Bild überhaupt nicht vorkommt.<br />

Verfahren zur Kompression Zur Kompression der Bilddaten wird der sogenannte<br />

Deflate-Algorithmus verwendet, ein gerade in der OpenSource-Gemeinde sehr berühmter<br />

<strong>und</strong> oft verwendeter Algorithmus, der zum Beispiel auch bei gzip Verwendung findet.<br />

Die Kompression erfolgt bei PNG üblicherweise in drei Schritten, nämlich ” Vorfiltern“,<br />

35


” LZ77-Kompression“ <strong>und</strong> Huffman-Codierung“, wobei zur Zeit leider viele Programme<br />

”<br />

standardmäßig keine Vorfilter verwenden, durch die eine erhebliche Ersparnis erreicht<br />

würde. Außerdem kann eine Interlacing-Methode angegeben werden, die eventuell eine<br />

schnellere Erkennbarkeit der Grafik bei niedrigeren Bandbreiten in Netzwerken erlaubt<br />

[Deu96].<br />

Vorfilter Grafiken vom Typ PNG können deutlich platzsparender sein als andere Grafiken,<br />

insbesondere als solche vom Typ GIF. Ein großer Vorteil von PNG ist der in der<br />

Kompressionsphase gegebenenfalls angewandte Vorfilter. Ein solcher Vorfilter kann z. B.<br />

eine eingelesene Bildzeile mit der vorigen Bildzeile vergleichen <strong>und</strong> Verbindungen zwischen<br />

gleichen Farben hergestellen.<br />

Vorfilter werden immer byteweise ausgeführt <strong>und</strong> stehen deshalb nicht in direkter<br />

Abhängigkeit vom Farbtyp oder der Farbtiefe der Grafik. Nichtsdestotrotz ist es für<br />

Grafiken mit weniger als 256 Farben besser, unkomprimiert in einer Palettengrafik gespeichert<br />

zu werden. Truecolor-Bilder sind meist sehr groß <strong>und</strong> eignen sich in den meisten<br />

Fällen für effizientes Vorfiltern. Der PNG-Standard kennt die folgenden Vorfilter:<br />

0 (None): Es wird kein Vorfilter angewendet. Dies ist leider die Standardeinstellung der<br />

meisten Bildbearbeitungsprogramme.<br />

1 (Sub): Es wird nicht der eigentliche Bytewert sondern die Differenz zum vorigen links<br />

liegenden Pixelwert gespeichert.<br />

2 (Up): Es wird nicht der eigentliche Bytewert sondern die Differenz zum Wert des<br />

Pixels in der darüber liegenden Zeile gespeichert.<br />

3 (Average): Es wird die Differenz aus dem eigentlichen Wert <strong>und</strong> dem Mittelwert des<br />

links <strong>und</strong> darüber liegenden Pixels gespeichert.<br />

4 (Paeth): Dieser Filter liest für ein Pixel den links daneben liegenden, den darüber<br />

liegenden <strong>und</strong> den links darüber liegenden Pixelwert aus, addiert den links <strong>und</strong><br />

darüber liegenden Wert <strong>und</strong> zieht den links darüber liegenden Pixelwert von der<br />

Summe ab. Anschließend wird für jeden der drei ausgelesenen Pixelwerte die Differenz<br />

zum errechneten Vergleichswert bestimmt <strong>und</strong> letztlich derjenige Pixelwert<br />

gespeichert, der am nächsten am Vergleichswert liegt [MA99].<br />

4.4 WAV<br />

Zusammenfassung In einer WAV-Datei werden Audiodaten in digitaler Form gespeichert.<br />

Die Audiodaten sind Abtastwerte, die die Amplitude zu einem bestimmten<br />

Zeitpunkt digital darstellen. Diese Abtastwerte, auch Samples genannt, werden in<br />

einer WAV-Datei fortlaufend abgelegt <strong>und</strong> ergeben somit den zeitlichen Verlauf einer<br />

Schwingung. Die Genauigkeit dieser digitalen Repräsentation, auch Qualität genannt,<br />

hängt von der Anzahl der Abtastwerte pro Zeiteinheit (üblich sind 44100 Mal in der<br />

36


Sek<strong>und</strong>e) <strong>und</strong> der Quantisierungsrate (beispielsweise 16 Bit pro Sample) ab.<br />

Das WAV-Containerformat setzt auf dem Resource Interchange File Format (RIFF)<br />

auf [wpw08]. RIFF ist ein Containerformat zur Speicherung von Multimedia-Daten,<br />

das 1991 von Microsoft <strong>und</strong> IBM entwickelt worden ist. Als Gr<strong>und</strong>lage für das RIFF-<br />

Dateiformat diente das von der Firma Electronic Arts 1985 eingeführte Interchange<br />

File Format (IFF). In RIFF-Dateien können unterschiedliche Multimedia-Ressourcen<br />

gespeichert werden. Dabei wird nach dem Prinzip vom tagged File Format im Header<br />

der Datentyp angegeben. Als mögliche Datentypen kommen BMP, WAV, AVI oder<br />

RTF in Frage.<br />

Zwar können in einer WAV-Datei auch komprimierte Daten abgespeichert werden, für<br />

die dann ein bestimmter Wert im Header gesetzt werden muss, jedoch liegt der Inhalt<br />

der WAV-Dateien in der Regel unkomprimiert vor. Aus diesem Gr<strong>und</strong> wird im Folgenden<br />

ausschließlich auf PCM-Rohdaten eingegangen. Ein Beispiel hierfür ist in Abbildung 6<br />

auf Seite 39 zu sehen.<br />

Aufbau des <strong>Formate</strong>s Da eine WAV-Datei immer in einem RIFF-Container enthalten<br />

ist, beginnt sie stets mit dem RIFF-Chunk, in dem dann der Datentyp festgelegt wird.<br />

Bits Feldname Beschreibung<br />

4 ChunkID Enthält die Buchstaben RIFF in ASCII-Form<br />

(5216491646164616 als big-endian).<br />

4 ChunkSize Hier wird die Gesamtgröße der Datei angegeben.<br />

Dabei werden die 8 Bytes der Felder ChunkID<br />

<strong>und</strong> ChunkSize nicht berücksichtigt.<br />

4 Format Enthält den Formattypen. In diesem Fall die<br />

Buchstaben WAVE<br />

(5716411656164516 als big-endian).<br />

Dem RIFF-Chunk folgt stets der Format-Chunk, in dem das Format <strong>und</strong> die Art der<br />

Darstellung der Audiodaten angegeben ist.<br />

37


Bits Feldname Beschreibung<br />

4 Subchunk1ID Enthält die Buchstaben fmt<br />

(66166d1674162016 big-endian form).<br />

4 Subchunk1Size Dies ist die Größe des folgenden Format-Chunks<br />

in Bytes. Bei PCM folgen stets 16 Bytes.<br />

2 AudioFormat Besagt, in welcher Form die Audiodaten vorliegen.<br />

Da wir von PCM ausgehen ist dieser Wert<br />

1.<br />

2 NumChannels Die Anzahl der Kanäle:<br />

Mono = 1, Stereo = 2, . . .<br />

4 SampleRate Abtastwerte pro Sek<strong>und</strong>e:<br />

z. B.: 8000, 22050, 44100<br />

4 ByteRate Bytes pro Sek<strong>und</strong>e. Die Byterate ergibt sich aus<br />

der Anzahl der Kanäle <strong>und</strong> der Anzahl der Abtastwerte<br />

pro Sek<strong>und</strong>e.<br />

2 BlockAlign Bytes pro Abtastwert.<br />

2 BitsPerSample Bits pro Zeiteinheit für einen Kanal.<br />

8 bits = 8, 16 bits = 16, . . .<br />

Der Data-Chunk enthält die Audiodaten <strong>und</strong> somit den <strong>Teil</strong> der Datei, der für<br />

steganographische Zwecke interessant ist. Der RIFF-Chunk <strong>und</strong> der Format-Chunk<br />

sollten bei einer Dateneinbettung nicht verändert werden.<br />

Bits Feldname Beschreibung<br />

4 Subchunk2ID Enthält die Buchstaben data<br />

(6416611674166116 als big-endian).<br />

4 Subchunk2Size Die Anzahl der Bytes der folgenden<br />

Audiodaten in diesem<br />

Chunk.<br />

* Data Die Audiodaten. Dabei werden<br />

die Audioinformationen<br />

aller Kanäle chronologisch abgelegt.<br />

Das ist in Abbildung 6<br />

gut zu erkennen.<br />

4.5 PDF<br />

Zusammenfassung Bei dem Portable Document Format (PDF) handelt es sich um<br />

ein Dateiformat für Dokumente, die mit Einschränkungen nicht mehr verändert werden<br />

sollen. PDF wurde von der Firma Adobe Systems [ado08a] entwickelt. Die Spezifikationen<br />

sind zwar offen <strong>und</strong> von der ISO genormt, Adobe behält sich aber das Copyright an diesen<br />

vor.<br />

38


Abbildung 6: Beispiel für eine unkomprimierte WAV-Datei. [pcm08]<br />

Eine PDF-Datei hat den Vorteil, auf allen betrachtenden oder verarbeitenden Systemen<br />

unabhängig von der Konfiguration (verwendetes Betrachtungsprogramm, installierte<br />

Schriften, Art des Druckers) gleich auszusehen. Dies mag ein Gr<strong>und</strong> sein, warum PDF<br />

sehr weit verbreitet ist <strong>und</strong> als wichtiges Format für die Archivierung, den Austausch<br />

oder den Druck von Dokumenten gilt.<br />

Neben fast allen gängigen Office-Paketen <strong>und</strong> dem Textsatzsystem L ATEXexistieren<br />

viele Programme <strong>und</strong> Konverter, die PDF-Dateien beispielsweise aus Postscript- oder<br />

HTML-Dateien erzeugen können [wp08].<br />

Aufbau des <strong>Formate</strong>s PDF ist ein vektorbasiertes Seitenbeschreibungsformat, welches<br />

die freie Skalierung des Inhalts ermöglicht. Ein PDF-Dokument ist aus vielen so genannten<br />

Objekten aufgebaut, welche <strong>Teil</strong>e des Inhalts repräsentieren. Eine einzelne Seite kann<br />

dabei aus h<strong>und</strong>erten Objekten bestehen. Objekte können verschiedenster Art sein.<br />

Ein Textobjekt besteht aus einem oder mehrerer Glyphen die Zeichen repräsentieren.<br />

Das Aussehen dieser Glyphen wird in einer separaten Datenstruktur, einer so genannten<br />

Font als Vektorgrafik definiert.<br />

Ein Pfadobjekt definiert eine Menge von verb<strong>und</strong>enen <strong>und</strong> nicht verb<strong>und</strong>enen Punkten,<br />

Linien <strong>und</strong> Flächen, die so eine Vektorgrafik bilden.<br />

Ein Bildobjekt ist eine rechteckige Rastergrafik, die beispielsweise ein Bild in das<br />

39


Dokument integriert. Diese Bildobjekte können bei Bedarf mittels JPEG, JPEG2000<br />

oder LZW komprimiert werden.<br />

Dies sind die wichtigsten Objekte, jedoch gibt es noch eine Vielzahl weiterer. Die Reihenfolge<br />

der Objekte in der Datei ist nicht festgelegt, hat keine semantische Bedeutung<br />

<strong>und</strong> kann somit vom Ersteller frei definiert werden. Um dies zu ermöglichen enthält<br />

ein PDF-Dokument am Dateiende eine Referenztabelle, die die Position jedes Objektes<br />

innerhalb der Datei enthält.<br />

Die Geometrie einer einzelnen Seite wird durch verschiedene Arten von Boxen, also<br />

rechteckigen Rahmen, definiert. Die MediaBox beschreibt die Größe des Ausgabemediums.<br />

Alle anderen Boxen müssen sich innerhalb dieser befinden.<br />

Die CropBox beschreibt den Bereich der Seite, der auf der Ausgabe ausgegeben werden<br />

soll. Meist ist diese nicht kleiner als die MediaBox.<br />

Die BleedBox <strong>und</strong> die TrimBox beinhalten den Platz auf der Seite, der letztendlich nur<br />

bedruckt wird. Die BleedBox ist etwas größer, da sie noch einen Rahmen, den Beschnitt,<br />

beinhaltet, der für die Drucktechnik wichtig ist.<br />

Letztendlich bildet eine ArtBox den Rahmen für ein Objekt. Bis auf die MediaBox<br />

sind alle Boxen optional [Ado06].<br />

4.6 SVG<br />

Zusammenfassung Scalable Vector Graphics, kurz SVG, sind Vektorgrafiken, welche<br />

in einem standardisierten XML-Format gespeichert werden. Es ist möglich, dass der<br />

Dateiinhalt mittels gzip komprimiert wurde, dann muss die Datei vor der Bearbeitung<br />

zunächst dekomprimiert werden. Ein derart komprimiertes SVG hat die Dateiendung<br />

’.svgz’, unkomprimierte SVG-Bilder, deren Inhalt im Klartext vorliegt, haben die Dateiendung<br />

’.svg’.<br />

Aufbau des <strong>Formate</strong>s Die Datei beginnt üblicherweise mit einer XML-Deklaration:<br />

<br />

<br />

Die eigentlichen SVG-Daten befinden sich zwischen einem einleitenden - <strong>und</strong><br />

einem abschließenden -Tag. Dazwischen befinden sich die Beschreibungen der<br />

verschiedenen Elemente der Vektorgrafik.<br />

Eine kleine Übersicht der verschiedenen Tags:<br />

• beschreibt einen Pfad.<br />

• beschreibt einen Kreis.<br />

• beschreibt eine Linie.<br />

• ... beschreibt <strong>und</strong> definiert einen Text.<br />

40


Über die einzelnen grafischen Elemente hinaus gibt es Tags, welche zur Beschreibung<br />

von Animationen genutzt werden können. Darüber hinaus ist Scripting mit einem<br />

JavaScript-Dialekt <strong>und</strong> das Einfügen von grafischen Effekten <strong>und</strong> Filtern möglich.<br />

Ein Tag dient nur der Einordnung eines grafischen Elements, es fehlt die genaue Beschreibung<br />

der Eigenschaften (Höhe, Breite, Liniendicke, etc.). Dies wird durch die Attribute<br />

eines Tags erreicht, welche innerhalb des einleitenden Tags in der Form von<br />

Name=”Wert” angegeben werden [Wik08g].<br />

4.7 CSS<br />

Zusammenfassung Cascading Style Sheets sind eine Ergänzung zu HTML, mit der<br />

sich die Struktur eines HTML-Dokuments vom Layout trennen lässt.<br />

CSS wurde mit HTML 4.0 im Jahr 1997 vom W3C offiziell als Standard verabschiedet.<br />

Ein sauberes HTML 4.0+ Dokument verwendet keine Formatierungsangaben wie beispielsweise<br />

Farbe <strong>und</strong> Schriftart, sondern gibt lediglich die Struktur für den Inhalt vor.<br />

Ein Stylesheet, ins Deutsche übersetzt ” Formatvorlage“, enthält zentral die eigentlichen<br />

Layoutangaben. Dadurch werden zum einen Red<strong>und</strong>anzen vermieden <strong>und</strong> zum anderen<br />

wird ein schnelles Umgestalten des Webseiten-Layouts vereinfacht.<br />

Aufbau des <strong>Formate</strong>s Ein CSS kann innerhalb eines HTML-Dokuments definiert werden:<br />

<br />

. kommentar { font −s t y l e : i t a l i c ;<br />

c o l o r : red ;<br />

font −s i z e : 12 pt }<br />

<br />

Die gängigere Methode ist jedoch, einen Link auf eine CSS-Datei anzugeben, der gleichzeitig<br />

von verschiedenen HTML-Dateien genutzt werden kann [Bol08]:<br />

<br />

Die Datei-Endung für eine Stylesheet-Datei ist .css.<br />

CSS besteht aus Regeln. Eine Regel definiert durch Kommata abgetrennte Selektoren.<br />

Jene stehen vor geschweiften Klammern <strong>und</strong> innerhalb eines solchen Klammerblocks<br />

befinden sich durch Semikolons getrennt Eigenschaft-Werte-Paare: jeder Eigenschaft<br />

folgt nach einen Doppelpunkt ein oder mehrere Werte. Auch mehrere durch Blanks<br />

getrennte Worte sind erlaubt.<br />

/∗ CSS−Regel ∗/<br />

S e l e k t o r [ , S elektor2 , . . . ] {<br />

Eigenschaft −A: Wert−A;<br />

Eigenschaft −B: Wert−B<br />

}<br />

41


Eine Übersicht aller Selektoren ist hier zu finden: [W3C08b].<br />

Ein konkretes CSS-Beispiel sieht so aus:<br />

p . note {<br />

p o s i t i o n : r e l a t i v e ;<br />

l e f t : 15%;<br />

width : 80%;<br />

padding : 30px ;<br />

padding−bottom : 45px ;<br />

border : 1px s o l i d black ;<br />

l i n e −h e i g h t : 1 . 5em ;<br />

c o l o r : black ;<br />

font −weight : bold ;<br />

text −a l i g n : j u s t i f y ;<br />

backgro<strong>und</strong>−c o l o r : #e e e e e e<br />

}<br />

Auf folgende Weise wird diese Regel in HTML benutzt:<br />

<br />

Dies i s t e i n k l e i n e r Testabsatz . Dies i s t e i n k l e i n e r Testabsatz .<br />

. . .<br />

<br />

Abbildung 7 zeigt die Ausgabe des Web-Browsers [Wik08b]. Eine Auflistung <strong>und</strong> Be-<br />

Abbildung 7: Browser-Interpretation von CSS <strong>und</strong> HTML<br />

schreibung aller möglichen Werte gibt es hier [Blo08]. Weitere Informationen gibt es<br />

direkt auf der CSS-Homepage des W3C [W3C08a].<br />

42


5 Vorhandene steganographische <strong>Algorithmen</strong><br />

5.1 Gr<strong>und</strong>lagen<br />

Die nachfolgenden <strong>Algorithmen</strong> dienen der steganographischen Einbettung in Dateien<br />

unterschiedlicher <strong>Formate</strong>. Damit geht einher, dass die Funktionsweise sich von Algorithmus<br />

zu Algorithmus unterscheidet, gerade in Abhängigkeit zum verwendeten Dateiformat.<br />

Die gr<strong>und</strong>legenden Begriffe <strong>und</strong> Vorgänge, die alle <strong>Algorithmen</strong> gemeinsam haben,<br />

werden hier kurz vorgestellt. Formatspezifische Begriffe können den vorangegangen Beschreibungen<br />

der einzelnen Dateiformate entnommen werden.<br />

Ein steganographischer Algorithmus verwendet als Eingabe eine Datei, das so genannte<br />

Cover. Ein Cover kann zum Beispiel eine Bild-Datei oder eine Audio-Datei sein, die<br />

steganographische Einbettung funktioniert aber auch mit Textdateien oder beinahe beliebigen<br />

anderen Dateien. Gr<strong>und</strong>legend kann ein Cover demnach als Vektor von Bits<br />

aufgefasst werden. Nach Anwendung des Algorithmus wird aus dem Cover ein Steganogramm,<br />

auch Stego-Datei genannt, also eine Datei, die dem eingegebenen Cover<br />

möglichst gleicht. Dies bedeutet, dass das Aussehen oder der Klang als für den Menschen<br />

wahrnehmbare Eigenschaften, als auch die binäre Repräsentation der Datei, wie sie auf<br />

dem Rechensystem gespeichert oder über ein Netzwerk verschickt wird, möglichst geringfügig<br />

vom eingegebenen Cover abweicht. Weiterhin enthält das Steganogramm nach<br />

Anwendung des Algorithmus die Geheimnachricht. Diese kann eine beliebige Kette<br />

von Bits sein, also eine gewöhnliche Text-Nachricht in beispielsweise ASCII- oder UTF-<br />

8-Formatierung, oder eine binäre Nachricht in Form einer anderen Datei. Die Anwendung<br />

des Algorithmus auf ein Cover nennen wir Einbettung.<br />

Um die Geheimnachricht in das Cover einzubetten, wird die Binärrepräsentation des<br />

Covers, also die darin enthaltenen Bits, die nur die Werte Eins oder Null annehmen<br />

können, geändert. Ein niederwertigstes Bit, auch Least Significant Bit genannt,<br />

beschreibt dabei dasjenige Bit einer Binärzahl, dessen Wertigkeit am geringsten ist, das<br />

höherwertigste Bit oder Most Significant Bit hingegen das Bit mit der höchsten<br />

Wertigkeit. Für die Schreibweise verwenden wir das sogenannte Little Endian-Format,<br />

das zum Beispiel von Prozessoren der Firma Intel verwendet wird. Dies bedeutet, dass<br />

eine Binärzahl von links nach rechts beginnend mit dem höherwertigsten Bit geschrieben<br />

<strong>und</strong> auf gleiche Art <strong>und</strong> Weise im Arbeitsspeicher eines Rechensystems abgelegt<br />

wird. Dabei steht das niederwertigste Bit in der kleinsten Speicheradresse, nachfolgende<br />

höherwertigere Bits stehen in Speicherzellen mit größeren Adressen.<br />

Ein Bit vorn oder links anzuhängen heißt demnach, ein noch höherwertigeres Bit als<br />

das bisher höherwertigste Bit der Binärzahl hinzuzufügen, ein Bit hinten oder links<br />

anzuhängen bedeutet analog, dass alle vorhandenen Bits in ihrer Wertigkeit um eine<br />

Zweierpotenz aufsteigen <strong>und</strong> ein neues niederwertigstes Bit hinzugefügt wird, also eine<br />

Eins oder eine Null. Selbiges gilt für die Geheimnachricht, die ebenfalls als Vektor aus<br />

Bits aufzufassen ist.<br />

Die Entscheidung, welche <strong>Teil</strong>e des Covers vom Algorithmus geändert werden, um die<br />

Geheimnachricht einzubetten, wird bei einigen <strong>Algorithmen</strong> von einem Pseudozufalls-<br />

43


zahlengenerator, kurz PRNG für Pseudo Random Number Generator, übernommen.<br />

Dieser verwendet einen eigenen Algorithmus, um <strong>–</strong> ausgehend von einem Startwert, dem<br />

Random Seed oder Stego-Key, zum Beispiel einem Passwort <strong>–</strong> Zahlen pseudozufällig<br />

zu generieren. So kann die gleiche Zahlenfolge unter Verwendung des gleichen Algorithmus<br />

<strong>und</strong> Passwortes auf Seiten des Senders wie des Empfängers eines Steganogramms<br />

hergestellt werden. Die Steganographie ist zum versteckten Übertragen von Informationen<br />

gedacht, daher betrachten wie Sender <strong>und</strong> Empfänger eines Steganogramms als<br />

zwei Klienten in einem großen, offenen Netzwerk von Rechensystemen, wie dem Internet.<br />

Alle Beschreibungen der Sicherheit von <strong>Algorithmen</strong> oder Angriffen auf diese verwenden<br />

das Prinzip von Kerckhoff, das heißt, die beschriebenen <strong>Algorithmen</strong> sind öffentlich<br />

<strong>und</strong> können von jedermann frei studiert oder verwendet werden. Die Sicherheit der steganographischen<br />

<strong>Algorithmen</strong> wird also daran bemessen, wie hoch die Wahrscheinlichkeit<br />

ist, in dem Steganogramm enthaltene Daten zu finden. Bereits das Finden von solchen<br />

Datenmustern, nicht erst das Auslesen der Geheimnachricht, gilt als erfolgreicher Angriff<br />

auf die steganographischen <strong>Algorithmen</strong>. Gleichzeitig soll, wie bereits erwähnt, ein<br />

menschlicher Betrachter nicht imstande sein, mit seinen eigenen Sinnen zu erkennen, ob<br />

es sich um eine gewöhnliche Datei oder ein Steganogramm handelt.<br />

Die Ausbettung einer Geheimnachricht beschreibt die Anwendung des Algorithmus,<br />

welche die zuvor in der Einbettung veränderten Bits findet <strong>und</strong> daraus die Geheimnachricht<br />

zusammensetzt. Dieser Vorgang basiert zunächst einmal auf der Funktionsweise<br />

des Algorithmus selbst, das Auslesen der Geheimnachricht kann bei einigen <strong>Algorithmen</strong><br />

aber auch erst durch die Eingabe eines Passwortes oder das Setzen von Parametern<br />

möglich werden. Parameter sind dabei besondere Einstellungen von <strong>Algorithmen</strong>, um<br />

beispielsweise festzulegen, wie groß ein Block von Daten sein soll, der bei der Ein- <strong>und</strong><br />

Ausbettung bearbeitet wird. In solchen Fällen kann die Geheimnachricht nur dann ohne<br />

Fehlversuche ausgebettet werden, wenn dem Empfänger des Steganogramms das Passwort<br />

<strong>und</strong>/ oder die Parameter bekannt sind, die vom Sender eingegeben wurden.<br />

5.2 Einbettung in GIF-Dateien<br />

5.2.1 GIFShuffle<br />

Zusammenfassung GIFShuffle wurde im Januar 1998 von Matthew Kwan veröffentlicht.<br />

Im Januar 2003 folgte GIFShuffle 2.0.<br />

Der Algorithmus kodiert Geheimnachrichten über die Reihenfolge der Farbeinträge in<br />

der Farbpalette.[?]<br />

Algorithmus Zunächst wird der Binärrepräsentation der Geheimnachricht eine Eins<br />

vorn angestellt, um die Zahl eindeutig zu machen für den Fall, dass sie mit einer oder<br />

mehreren Nullen beginnen sollte. Danach werden die einzigartigen Farben im Cover, also<br />

die Farben, die in der Farbpalette nur einmal vorkommen, gezählt. Da die Nachricht<br />

über die Permutation der Farben eingebettet wird, kann nun bereits getestet werden, ob<br />

die Nachricht überhaupt eingebettet werden kann. Gilt m > n! − 1, wobei m die Nachrichtenlänge<br />

<strong>und</strong> n die Anzahl einzigartiger Farben im unveränderten Bild beschreibt,<br />

44


so ist die Nachricht zu groß, um eingebettet zu werden.<br />

Wenn die Nachricht eingebettet werden kann, werden die einzigartigen Farben der Farbpalette<br />

des Covers in natürliche Ordnung gebracht, indem die Werte für Rot mit 256 2 ,<br />

die für Grün mit 256 1 <strong>und</strong> die für Blau mit 256 0 multipliziert <strong>und</strong> anschließend diese<br />

Werte addiert werden (r · 65536 + g · 256 + b). Im Anschluss wird in einer Iteration jede<br />

einzigartige Farbe der Palette auf Position m mod i gesetzt, wobei i die Iterationsvariable<br />

(1...n) beschreibt. Sollte dabei ein Index bereits belegt sein, werden alle bereits<br />

eingefügten Farben inkrementiert, also in der Palette um einen Index nach oben verschoben.<br />

Schließlich werden die nicht eindeutigen Farben hinten an die Farbpalette angehängt<br />

<strong>und</strong> die Pixeldaten, welche die Farben in der Farbpalette indizieren, so angepasst, dass<br />

sie die gleiche Farbe wie vor der Einbettung indizieren.<br />

Der Empfänger des Stego-Bildes kann nun aus der Reihenfolge der Paletteneinträge<br />

auf die Geheimnachricht schließen. Der Algorithmus stellt die natürliche Ordnung der<br />

einzigartigen Farben her, iteriert durch diese Farben <strong>und</strong> berechnet bei jeder Iteration<br />

m = m · (n − i) + p, wobei m die Nachricht, n die Anzahl einzigartiger Farben in der<br />

Farbpalette, i die Iterationsvariable (1...n) <strong>und</strong> p der Index der Farbe in der Farbpalette<br />

in natürlicher Ordnung ist.<br />

Bei n Farben können log2(n!) Bits eingebettet werden. Da die meisten Farbpaletten<br />

gemäß der Helligkeit oder den Vorkommen im Bild geordnet sind, gilt ein Algorithmus,<br />

der Paletteneinträge umsortiert, generell als sehr unsicher. Des weiteren ist eine Permutation,<br />

die aus der natürlichen Ordnung der Farbpalette abgeleitet ist, als äußerst unsicher<br />

zu bewerten, weil ein jeder die mit der natürlichen Ordnung vorgegebene anfängliche<br />

Permutation der Einträge kennt.<br />

5.2.2 FriRui<br />

Zusammenfassung Der Algorithmus stammt aus einer Veröffentlichung von Jessica<br />

Fridrich <strong>und</strong> Du Rui, mit dem Titel ” Secure Steganographic Methods for Palette<br />

Images“([Jir01]) Mit dem Algorithmus lassen sich Daten in palettenbasierten Bildern<br />

verstecken. Die Funktionsweise des Algorithmus wird für GIF Bilder im Folgenden<br />

erläutert.<br />

Algorithmus Anhand folgender Formel berechnet man die Distanzen aller Farben in<br />

der Farbpalette.<br />

dij = (Ri − Rj) + (Gi − Gj) + (Bi − Bj) (4)<br />

dij ist die Distanz zweier Farben i <strong>und</strong> j. R, G <strong>und</strong> B stehen für die einzelnen Farbwerte:<br />

Rot, Grün <strong>und</strong> Blau. Nun kann man Tripel folgender Form erstellen.<br />

((Ri, Gi, Bi), (Rj, Gj, Bj), dij) (5)<br />

Diese Tripel lassen sich nun anhand der Distanz aufsteigend sortieren. Die Farben in<br />

dieser geordnete Menge von Tripeln trägt man nun in eine gesonderte Tabelle ein <strong>und</strong><br />

verändert dabei eventuell die Parität. Die Parität jeder Farbe berechnet man, indem<br />

45


man die einzelnen RGB-Farbwerte addiert. Ist das Ergebnis dieser Addition gerade, so<br />

ist die Parität null, ist es ungerade, so ist die Parität eins. Beim Eintragen der Farben<br />

aus den einzelnen Tupeln der geordneten Tupelmenge geht man folgendermaßen vor:<br />

Ist keine der betrachteten Farben in der neuen Tabelle, verändert man die Paritäten der<br />

Farben so, dass sie sich unterscheiden. Ist eine der betrachteten Farben in der Tabelle, so<br />

verändert man die andere Farbe, so dass sich die Paritäten unterscheiden. Diesen Vorgang<br />

wiederholt man, bis man alle Farben in die neue Tabelle eingetragen hat. Abbildung 8<br />

verdeutlicht diesen Vorgang.<br />

Möchte man nun ein Nachrichtenbit mit Wert Null einbetten <strong>und</strong> ist die Parität der<br />

Originalfarbe im Bild gleich Eins, so verwendet man die Farbe mit geringster Distanz zum<br />

Original, welche die Parität Null hat. Entsprechend verfährt man für den umgekehrten<br />

Fall.<br />

Einbettung in mehrere Pixel Das Bild wird in Pixelketten aufgeteilt. Die Parität über<br />

alle Pixel in dieser Kette wird gebildet. Es muss nur ein Farbwert in der Kette geändert<br />

werden. Hierzu kann man das Unauffälligste auswählen.<br />

Aus der Veröffentlichung geht hervor, dass eine Kettenlänge von 2 die Anzahl an<br />

Änderungen um 30% verringert.<br />

• Vorteil: Je weniger Änderungen, desto schwerer durch Analyseverfahren aufzuspüren.<br />

• Nachteil: Je mehr Pixel in einer Kette, desto niedriger die Einbettungsrate.<br />

Einbettung nach vorheriger Analyse Berücksichtigt die Anordnung der Bits im Cover.<br />

Einfarbige Bereiche werden beispielsweise ausgelassen. Nur Pixel in deren Umgebung sich<br />

x verschiedene Farben befinden, werden berücksichtigt.<br />

Einbettung während Farbreduktion Man nutzt die Effekte der Farbreduktion um Daten<br />

einzubetten. Bei diesem Verfahren wird nicht die Originalfarbe verwendet die der<br />

Farbreduktionsalgorithmus ermittelt, sondern die nächstgelegene Farbe mit der passenden<br />

Parität. Bei statistischen Analysen fällt dies nicht so sehr auf, da nur Pixel verändert<br />

werden, die sich schon durch die Farbreduktion hervorheben.<br />

Methode 1 Man teilt das Bild in Blöcke zu 3x3 Pixeln. Man bildet die Parität über den<br />

ganzen Block. Nun bestimmt man eine Funktion anhand derer man Werte für die MSBs<br />

berechnen kann. Man bestimmt einen Schwellwert, der zur Einbettung genutzt wird.<br />

Wird dieser Schwellwert nach der Einbettung in einen Block überschritten, so wird die<br />

Einbettung zwar durchgeführt, das Nachrichtenbit wird jedoch erneut in den nächsten<br />

Block eingeb<strong>und</strong>en. Der Empfänger betrachtet nun nur die Blöcke, die den Schwellwert<br />

nicht überschreiten.<br />

46


Palette (Farbwerte als int)<br />

Paritäten der Farbwerte<br />

Pixeldaten (Indizes auf Palette)<br />

Cover<br />

1 | 3 | 3 | 4<br />

1 | 1 | 1 | 0<br />

0 | 1 | 2 | 3<br />

D = { (1,2,0) , (1,3,1), (2,3,1), (0,1,2) , (0,2,2), (0,3,3) }<br />

-- wobei Tripel:= (Farbindex1, Farbindex2, Distanz)<br />

Indizes der Paletteneinträge<br />

Paritäten (NEU) der Einträge<br />

Pixeldaten vor Einbettung:<br />

Neue Paritäten der Einträge:<br />

Geheimnachricht:<br />

Pixeldaten nach Einbettung:<br />

C (Datenstruktur des Algorithmus)<br />

1 | 2 | 3 | 0<br />

1 | 0 | 0 | 0<br />

Cover -> Stego-Bild<br />

0 | 1 | 2 | 3<br />

0 | 1 | 0 | 0<br />

1 | 0 | 0 | 1<br />

1 | 2 | 2 | 1<br />

Abbildung 8: Ein Beispiel zum FriRui Algorithmus<br />

47<br />

Distanzen bestimmen<br />

Optimale Paritäten<br />

bestimmen<br />

Nachricht einbetten


Methode 2 Man teilt das Bild in Blöcke zu 2x2 Pixeln. Enthält ein Block mehr als 2<br />

verschiedene Farben, so wird für gut bef<strong>und</strong>en. Eine Farbe wird für gut bef<strong>und</strong>en, wenn<br />

alle 2x2-Blöcke, in denen sie enthalten ist, für gut bef<strong>und</strong>en wurden. Aus der Menge der<br />

Pixel mit guten Farben, wählt man diejenigen, die zur Einbettung der Geheimnachricht<br />

genutzt werden sollen, aus. Der Block muss nach der Einbettung immer noch als gut<br />

deklariert werden, ähnlich wie in Methode 1.<br />

5.2.3 Sortieren/Umsortieren<br />

Zusammenfassung Der Algorithmus von Corinna John, von uns ” Sortieren <strong>und</strong> Umsortieren“<br />

genannt, versteckt eine Nachricht durch Umsortieren der Einträge der Farbpalette.<br />

Die Funktionsweise ist demnach analog zu der von GIFShuffle [Joh].<br />

Algorithmus Der Algorithmus stützt sich auf die Tatsache, dass die Einträge der Farbpalette<br />

in GIF-Bildern, zumindest in der Theorie, willkürlich sortiert sein können. Die<br />

Einträge werden gemäß einer zuvor festgelegten Ordnung (z. B. aufsteigend nach Helligkeit)<br />

sortiert. Auch völlig unsortiert aussehende Paletten sind dabei erlaubt, so lange der<br />

Empfänger des Stego-Bildes diese kennt <strong>und</strong> damit die Nachricht reproduzieren kann.<br />

Dies ist ein eklatanter Vorteil gegenüber GIFShuffle, bei dem die Palette immer gemäß<br />

der natürlichen Ordnung der Farben sortiert wird <strong>und</strong> eine Einbettung demnach leicht<br />

reproduziert werden kann.<br />

Die Geheimnachricht wird eingebettet, indem man, wenn man eine Eins ausdrücken<br />

möchte, den Paletteneintrag in der sortierten Palette auf seiner aktuellen Position<br />

belässt, <strong>und</strong>, wenn man eine Null ausdrücken möchte, den Paletteneintrag um einen<br />

Index nach unten verschiebt. Sollte dabei der untere Index nicht frei sein, werden alle<br />

Farben mit einem unteren Index um eine Stelle weiter nach unten verschoben. An den<br />

Rändern der Palette wird zyklisch verschoben, das letzte Element kann also zum ersten<br />

Element werden.<br />

Der Empfänger des Stego-Bildes kann den gleichen Algorithmus noch einmal anwenden,<br />

wobei wiederum die festgelegte Ordnung hergestellt <strong>und</strong> anschließend die Indizes miteinander<br />

verglichen werden: Abweichnungen beschreiben eine Null, sonst Eins.<br />

Die Einbettungsrate liegt bei einem GIF-Bild mit 256 Farben bei 256 − 1 Bit, was 31<br />

ASCII-Zeichen entspricht. Nachdem aber die Mehrzahl aller GIF-Bilder zumindest irgendeine<br />

Sortierung enthält (z. B. nach Helligkeit oder Vorkommen der Farben im Bild),<br />

ist die Entdeckungswahrscheinlichkeit des Algorithmus hoch <strong>und</strong> dieser damit als unsicher<br />

einzustufen.<br />

5.3 Einbettung in JPEG-Dateien<br />

5.3.1 F5<br />

Zusammenfassung<br />

F5 wurde 2001 von Andreas Westfeld [Wes01] entwickelt <strong>und</strong> soll die statistischen Eigenschaften<br />

eines Trägers erhalten. Im Gegensatz zu den meisten LSB-Verfahren werden<br />

die einzelnen Frequenzkoeffizienten nicht überschrieben, sondern ihr absoluter Wert<br />

48


dekrementiert. Zudem werden Frequenzkoeffizienten mit Wert 1 genutzt, lediglich Koeffizienten<br />

mit Wert 0 werden nicht für dir Einbettung genutzt.<br />

F5 bedient sich der Matrixkodierung von Ron Crandall [Cra98], wodurch die Einbettungseffizienz<br />

gesteigert wird.<br />

Permutative Spreizung<br />

Bei F5 wird eine steganographische Nachricht nicht von oben nach unten in den Träger<br />

eingebettet, sondern mit Hilfe einer Permutation der Frequenzkoeffizienten in dem Träger<br />

verteilt. Die Permutation ist abhängig von einem Schlüssel, den sowohl Sender als auch<br />

Empfänger besitzen müssen.<br />

Matrixkodierung<br />

Bei der Matrixkodierung werden n änderbare Stellen eines Trägers zu einem Block (Kodewort)<br />

zusammengefasst. Um eine Nachricht x, bestehend aus k Stellen, in den Träger<br />

einzubetten wird geprüft, ob eine Hashfunktion f aus dem Kodewort bereits die Nachricht<br />

extrahieren kann: x = f(a), wobei a das Kodewort ist. Ansonsten muss das Kodewort<br />

so geändert werden, dass gilt x = f(a ′ ), wobei a ′ das veränderte Kodewort ist.<br />

Dabei darf die Anzahl der Änderungen (Hammingdistanz) d, obwohl die Matrixkodierung<br />

auch andere Modi erlaubt, bei denen 2, 3 oder mehr Stellen verändert werden<br />

müssen, bei F5 nicht größer als 1 sein: d(a, a ′ ) ≤ 1. Die Kodewortlänge ergibt sich bei<br />

einer Nachrichtenlänge k somit zu n = 2 k − 1<br />

Das folgende Beispiel verdeutlicht die Einbettung einer Nachricht, die aus zwei Bits x1,<br />

x2 besteht, in ein Kodewort a der Länge n = 3.<br />

x1 = a1 ⊕ a3, x2 = a2 ⊕ a3 ⇒ nichts ändern<br />

x1 �= a1 ⊕ a3, x2 = a2 ⊕ a3<br />

x1 = a1 ⊕ a3, x2 �= a2 ⊕ a3<br />

x1 �= a1 ⊕ a3, x2 �= a2 ⊕ a3<br />

⇒ a1 ändern<br />

⇒ a2 ändern<br />

⇒ a3 ändern<br />

Algorithmus<br />

Zu Beginn des F5-Algorithmus wird die Permutation der Frequenzkoeffizienten mittels<br />

eines Schlüssels initialisiert. Zudem wird mit Hilfe der maximalen Kapazität des Trägers<br />

<strong>und</strong> der Nachrichtengröße der Parameter k sowie die Kodewortlänge n bestimmt.<br />

Die Einbettung selbst ist in Abb.9 beschrieben.<br />

Die Bildung des Hashwerts in Zeile 3 wird nach folgendem Schema berechnet:<br />

hash(a) = ⊕ n i=1ai ∗ i<br />

Eigenschaften<br />

Beim Vergleich des eigentlichen JPEG Histogramms (Abb.10) <strong>und</strong> des Histogramms<br />

nach der Einbettung mittels F5 (Abb.11) fällt auf, dass die Häufigkeit der Frequenzkoeffizienten<br />

mit Wert 0 leicht ansteigt. Dieses ist auf die Schrumpfung zurückzuführen,<br />

49


C = JPEG-Frequenzkoeffizienten<br />

buffer[n] = n-stelliger Einbettungspuffer<br />

1 do<br />

2 buffer mit n Indiezes der Koeffizienten, die nicht 0 sind, füllen<br />

3 hash = k − -stelliger Hashwert<br />

4 msg = k Bits der Nachricht<br />

5 position = hash ⊕ msg<br />

6 if position �= 0 then<br />

7 Dekrementiere Betrag von C[buffer[position − 1]] um 1<br />

8 while C[buffer[position]] = 0<br />

Abbildung 9: F5 Algorithmus<br />

die entsteht, wenn bei der Einbettung ein Koeffizient mit einem Absolutwert von 1 zu 0<br />

dekrementiert wird <strong>und</strong> ein neuer Block zur Einbettung ausgewählt werden muss.<br />

Häufigkeit<br />

-4 -3 -2 -1 0 1 2 3 4<br />

JPEG-Koeffizienten<br />

Abbildung 10: JPEG-Histogramm<br />

Häufigkeit<br />

-4 -3 -2 -1 0 1 2 3 4<br />

Abbildung 11: F5-Histogramm<br />

JPEG-Koeffizienten<br />

Durch die Matrixkodierung bietet F5, in Abhängigkeit von der Einbettungsrate, eine<br />

relativ hohe Einbettungseffizienz wie in Abb.12 zu sehen.<br />

Dabei ergeben sich die einzelnen Kurven für die Einbettungsrate R, die Änderungsdichte<br />

D <strong>und</strong> die Einbettungseffizienz E aus den folgenden Formeln:<br />

Einbettungsrate (Nachrichtenlänge pro Kodewort):<br />

R(k) = k<br />

2 k − 1<br />

50


E(k)<br />

10<br />

9<br />

8<br />

7<br />

6<br />

5<br />

4<br />

3<br />

Abbildung 12: F5-Einbettungsrate<br />

2<br />

1 2 3 4 5 6 7 8 9 10<br />

k<br />

Änderungsdichte (Änderungen pro Nachrichtenbit):<br />

D(k) = 1<br />

2k<br />

Einbettungseffizienz (Eingebettete Bits pro Änderung):<br />

E(k) = R(k)<br />

D(k)<br />

Allerdings muss hierbei noch die Schrumpfung berücksichtigt werden, wodurch F5 eine<br />

Einbettungseffizienz von 1,5 bei maximaler Einbettungrate erreicht.<br />

Angriff<br />

In [FGH03] wird beschrieben, dass es möglich ist, Einbettungen mit F5 zu entdecken <strong>und</strong><br />

sogar die Länge der eingebetteten Nachricht zu ermitteln. Dazu wird das JPEG-Bild erst<br />

dekomprimiert <strong>und</strong> vier Zeilen abgeschnitten, wie in Abb. 13 gezeigt.<br />

Abbildung 13: Crop-Angriff<br />

51<br />

E(k)


Daraufhin wird ein Tiefpassfilter verwendet um Blockartefakte zu entfernen. Eine erneute<br />

Komprimierung mit der Quantisierungsmatrix des Trägers <strong>und</strong> ein darauf folgender<br />

Vergleich der Histogrammdaten der Frequenzkoeffizienten kann einen erhöhten Anteil an<br />

0-Koeffizienten aufdecken.<br />

5.3.2 MB2<br />

Zusammenfassung<br />

Bei der modellbasierten Steganographie liegt die Idee des perfekten Komprimierers zugr<strong>und</strong>e.<br />

Unter einem perfekten Komprimierer versteht man einen Komprimierer, der alle<br />

Eigenschaften der realen Welt kennt, also intern ein perfektes Modell der realen Welt<br />

besitzt. Somit sind komprimierte Bilder lediglich eine willkürliche Aneinanderreihung<br />

von Bits.<br />

Darauf aufbauend kann man davon ausgehen, dass ein perfekter Dekomprimierer aus<br />

willkürlichen Daten immer ein ursprüngliches Bild erstellen kann, da er ebenfalls ein<br />

perfektes Modell der realen Welt besitzt.<br />

Da es allerdings keinen perfekten Komprimierer gibt, versucht die modellbasierte Stegonographie,<br />

ein nahezu perfektes Modell P zu nutzen, um eine steganographische Nachricht<br />

in einen Träger einzubetten.<br />

Dabei werden für einen Menschen oder eine Maschine wahrnehmbare Eigenschaften des<br />

Trägers Xdet 1 genutzt um das Modell zu initialisieren. Vernachlässigbare Eigenschaften<br />

des Trägers Xindet werden bei MBS unter Berücksichtigung des Modells mit Hilfe<br />

eines arithmetischen Dekodierers so verändert, dass sie die Nachricht enthalten. Ein<br />

Empfänger kann somit wieder das Modell mit Hilfe von Xdet initialisieren <strong>und</strong> die eingebettete<br />

Nachricht extrahieren.<br />

Die genaue Arbeitsweise von MBS ist in Abb.14 dargestellt.<br />

Algorithmus<br />

Im Hinblick auf JPEG-komprimierte Grafiken bedeutet dies, dass es eine Aufteilung von<br />

wahrnehmbaren <strong>und</strong> vernachlässigbaren Eigenschaften gibt, wobei die vernachlässigbaren<br />

Eigenschaften einer JPEG-komprimierten Grafik die Positionen der Frequenzkoeffizienten<br />

im Bild darstellen. Im folgenden werden die Häufigkeit eines bestimmten Frequenzkoeffizienten<br />

c als hochpräzise Behälter hc bezeichnet.<br />

Dagegen stellen die wahrnehmbaren Eigenschaften eine Gruppe lc von im Histogramm<br />

benachbarter hochpräziser Behälter dar.<br />

⎧<br />

⎪⎨ h2c+1 + h2c wenn c < 0<br />

lc = h0<br />

⎪⎩<br />

h2c−1 + h2c<br />

wenn c = 0<br />

wenn c > 0<br />

1 In dem Artikel von Rainer Böhme <strong>und</strong> Andreas Westfeld [BW04] werden die Bezeichnung Xdet <strong>und</strong><br />

Xindet statt wie bei Phil Sallee [Sal05] α <strong>und</strong> β verwendet. Da diese Ausarbeitung sich öfter auf<br />

Andreas Westfeld beruft, sollen diese Bezeichnung das weitere Lesen vereinfachen<br />

52


Cover<br />

X<br />

X X<br />

det<br />

X X ’<br />

det<br />

X’<br />

indet<br />

indet<br />

Abbildung 14: MBS-Aufbau<br />

Model<br />

P<br />

X i ndet | X det<br />

Entropy<br />

Decoder<br />

Message<br />

M<br />

Diese Gruppe wird im Folgenden ” Behälter mit niedriger Präzision “genannt.<br />

Behälter mit niedriger Präzision sind somit <strong>Teil</strong> von Xdet <strong>und</strong> dürfen bei der Einbettung<br />

nicht verändert werden. Dagegen stellen hochpräzise Behälter Elemente von Xindet<br />

dar, die unter Berücksichtigung eines Models P verändert werden dürfen. Dabei muss<br />

der Algorithmus beachten, dass die Häufigkeit innerhalb eines Behälters mit niedriger<br />

Präzision unverändert bleibt <strong>und</strong> die Änderung weiterhin kohärent zum Modell sind.<br />

Modell<br />

Als Modell für die Häufigkeitsverteilung wird eine Cauchy Verteilung genutzt, die wie<br />

folgt definiert ist:<br />

p − 1<br />

P (c) = (|c/s| + 1)−p<br />

2s<br />

mit den Parametern p > 1 <strong>und</strong> s > 0 zum Anpassen des Modells an das Histogramm.<br />

Die zugehörige Dichtefunktion ist:<br />

�<br />

1<br />

D(c) = 2 (1 + |c/s|)1−p wenn c ≤ 0<br />

1 − 1<br />

2 (1 + |c/s|)1−p wenn c ≥ 0<br />

Dabei ist c jeweils der Index eines Behälters mit niedriger Präzision.<br />

Abb.17 zeigt das Histogramm einer mit JPEG komprimierten Grafik mit den jeweiligen<br />

hochpräzisen <strong>und</strong> niedriger präzisen Behältern (l−2 . . . l2). Die rote Linie beschreibt dabei<br />

das Modell, das über die Parameter p <strong>und</strong> s an die Behälter mit niedriger Präzision<br />

angepasst wurde.<br />

53


Häufigkeit<br />

l<br />

-2<br />

l<br />

-1<br />

l<br />

1<br />

-4 -3 -2 -1 0 1 2 3 4 JPEG Koeffizienten<br />

l<br />

2<br />

Abbildung 15: MBS-Modell<br />

Nach dem Anpassen des Modells wird die Wahrscheinlichkeit von jedem Koeffizienten<br />

innerhalb des Modells über die Dichtefunktion berechnet. Diese Wahrscheinlichkeiten<br />

werden mit der Nachricht <strong>und</strong> den Häufigkeiten der Koeffizienten an einen arithmetischen<br />

Dekodierer übergeben. Die Ausgabe des arithmetischen Dekodierers zusammen mit dem<br />

jeweiligen Behälter mit niedriger Präzision entspricht dem Wert des neuen Koeffizienten.<br />

Ein möglicher Dekodierer wird nach Sallee [Sal05] in [IHWC87] beschrieben.<br />

Blockreduzierung<br />

MB2 besitzt zudem einen Blockreduzierungsalgorithmus, der nur dann eine Einbettung<br />

zuläßt, wenn an den Rändern eines 8 × 8-Pixel-Blocks die Abhängigkeiten zu einem<br />

Nachbarblock nicht verletzt werden. Dadurch reduziert sich aber die Kapazität von MB2<br />

im Gegensatz zu MB1 um fast 50%.<br />

Eigenschaften<br />

Bei MBS ergibt sich die Einbettungsrate R, die Änderungsdichte D <strong>und</strong> die Einbettungseffizienz<br />

E aus der Wahrscheinlichkeit p einer von zwei Koeffizienten aus einem Behälter<br />

mit niedriger Präzision lc.<br />

Einbettungsrate (Durchschnittliche Anzahl von Bits die kodiert werden):<br />

R(p)c = −(p log 2(p) + (1 − p) log 2(1 − p))<br />

Änderungsdichte (Änderungen pro Nachrichtenbit):<br />

D(p)c = 2p(1 − p)<br />

Einbettungseffizienz (Eingebettete Bits pro Änderung):<br />

E(p)c = R(p)<br />

D(p)<br />

54


E(p)<br />

4<br />

3.5<br />

3<br />

2.5<br />

Abbildung 16: MBS-Einbettungsrate<br />

2<br />

0 0.1 0.2 0.3 0.4 0.5<br />

p<br />

0.6 0.7 0.8 0.9 1<br />

Wie in Abb. 16 zu sehen ist, sinkt die Einbettungseffizienz E(p)c nie unter 2 für<br />

0 < p < 1.<br />

Angriff<br />

Bisher wurde immer davon ausgegangen, dass die Häufigkeit von Frequenzkoeffizienten<br />

kontinuierlich mit steigender Frequenz abnimmt.<br />

Dies ist aber nicht immer der Fall, je nach Art des Bildes <strong>und</strong> je nach Aufnahmegerät<br />

kann ein Träger eine erhöhte Häufigkeit von Frequenzen in äußeren Bereichen<br />

aufzeigen. Diese Besonderheit wird von dem verwendeten Modell nicht abgedeckt wie<br />

in Abb. 17 ersichtlich. Bei der Einbettung durch MBS würde diese Besonderheit unter<br />

Umständen entfernt werden, da Änderungen kohärent zum zugr<strong>und</strong>e liegenden Modell<br />

bleiben müssen.<br />

Bei genügend statistischen Daten kann diese Veränderung der Frequenzkoeffizienten daher<br />

durch einen Vergleich der erwarteten <strong>und</strong> der vorhandenen Koeffizienten aufgedeckt<br />

werden. Nach [BW04] ist die Wahrscheinlichkeit schon bei 50%, dass eine steganographische<br />

Nachricht entdeckt werden kann, wenn mehr als 40% der möglichen Kapazitat<br />

eines Trägers genutzt werden.<br />

5.3.3 Perturbed Quantization <strong>–</strong> PQ<br />

Zusammenfassung In [Fri05b] beschreiben Jessica Fridrich <strong>und</strong> weitere Autoren eine<br />

Möglichkeit, Nachrichten mittels Wet Paper Codes, kurz WPC, in JPEG-Koeffizienten<br />

zu verstecken.<br />

55<br />

E(p)


Häufigkeit<br />

-4 -3 -2 -1 0 1 2 3 4 JPEG Koeffizienten<br />

Abbildung 17: JPEG-Histogramm mit erhöhter Häufigkeit von hohen Frequenzkoeffizienten<br />

Wet-Paper-Codes <strong>–</strong> WPC Grob übersetzt bedeutet WPC ” Schreiben auf nassem Papier“<br />

[Fri05a]. Der Sender kennt die nassen Stellen auf dem Papierstück, <strong>und</strong> meidet<br />

beim Beschreiben diese Regionen, da die Tinte dort micht haften bleibt. Ein weiterer<br />

Vergleich, der dem Problem etwas näher kommt, ist das Beschreiben eines Speichers mit<br />

defekten Zellen. Dabei gibt es insgesamt n Speicherzellen, von denen n − k fest auf Null<br />

oder Eins stehen. Der Sender, dem die defekten Stellen bekannt sind, muss die funktionierenden<br />

derartig beschreiben, dass der Empfänger, der keine Orts-Kenntnis über die<br />

defekten Bits besitzt, die ursprüngliche Nachricht wiederherstellen kann.<br />

Einbettung Die Shannon-Kapazität des Speichers, also die maximale Grösse der zu<br />

übermittelnden Nachricht, ist genau k. Folgende Definitionen werden zur Lösung des<br />

Problems benutzt:<br />

• xi ∈ J, wobei J = {0 . . . 255} <strong>und</strong> i ∈ {0, . . . , n}<br />

• S(x) sei eine Abbildung (hier einfacherweise von x auf das LSB von x) auf die<br />

Cover-Symbole<br />

• bx= (S(x1), S(x2) . . . , S(xn)) Bit-Vektor der Cover-Symbole<br />

Die nicht-defekten Symbole des Speichers bzw. des Trägermediums xi könnten nun<br />

verändert werden nach yi, <strong>und</strong> by= (S(y1), S(y2) . . . , S(yn)) ist dann der Vektor mit<br />

der eingebetteten Nachricht. Der Empfänger sieht nur nur by. Letzteres stellt also die<br />

LSBs unseres modifizierten Trägermediums dar.<br />

Die als Bit-Vektor dargestellte Nachricht s= (s1, s2, . . . , sm) mit der Länge m soll nun<br />

vom Sender eingebettet werden. Für by muss gelten:Dby = s.<br />

Dabei ist D eine binäre m×n-Matrix, die sowohl dem Sender als auch dem Empfänger<br />

bekannt sein muss. Sie wird pseudorandomisiert aus dem Stego-Key erzeugt. Das lineare<br />

Gleichungssystem aus Formel (??) lässt sich nicht für beliebige Matrizen D lösen; die<br />

Unveränderlichkeit der n − k Elemente des Vektors y erschwert die Problemstellung<br />

56


k Gauß[sec] LT[sec] P<br />

1000 0.023 0.008 43%<br />

10000 17.4 0.177 75%<br />

30000 302 0.705 82%<br />

100000 9320 3.10 90%<br />

Tabelle 2: Laufzeitvergleich zwischen Gauß-Elimination <strong>und</strong> Matrix LT Prozess in<br />

Abhängigkeit von der Nachrichtenlänge k, wobei P die Wahrscheinlichkeit<br />

ist, dass die Nachricht erfolgreich eingebettet werden kann.<br />

zusätzlich. Daher ist eine erfolgreiche Einbettung nicht garantiert. Kann jedoch eine<br />

Lösung gef<strong>und</strong>en werden, so ist es dem Empfänger möglich, mittels Gleichung (??),<br />

seiner Kenntnis über D <strong>und</strong> den Daten des veränderten Trägermediums by die Nachricht<br />

s auszurechnen.<br />

Um die defekten Stellen mit einzubeziehen, wird die Gleichung nun umgeschrieben:<br />

Dby = s ⇔ Dv = s − Dbx , mit v = by − bx<br />

Alle defekten Stellen in v sind Nullen, da sie nicht verändert werden können. Durch Entfernung<br />

dieser Zeilen wird v zu einem k ×1-Vektor transformiert, wobei die Bezeichnung<br />

erhalten bleibt. Dadurch schreibt sich (??) so:<br />

Hv = z , (6)<br />

wobei H eine m × k Matrix darstellt, die durch Entfernen derselben Zeilen aus D<br />

gewonnen wird, <strong>und</strong> z = s − Dbx ist. Die Lösung v dieser Gleichung ergibt die Bits,<br />

welche verändert werden müssen.<br />

Matrix-LT-Prozess Gleichung (6) kann durch Gauß- Elimination gelöst werden. Durch<br />

die hohe Komplexität von O(n 3 ) hätte dies allerdings sehr lange Laufzeiten für große<br />

Datenmengen zur Folge.<br />

LT Codes wurden 2005 von Michael Luby vorgeschlagen, daher steht die Abkürzung LT<br />

für Luby Transform. Der hier beschriebene Matrix-LT-Prozess mit einer Komplexität<br />

von O(n ln(k/σ)) ist signifikant schneller, wie in Tabelle 2 zu sehen ist.<br />

LT-Codes Die gr<strong>und</strong>legende Idee dahinter ist es, die Matrix H aus Formel (6) so zu<br />

erzeugen, dass sich das Gleichungssystem einfach lösen lässt.<br />

Abbildung 18 zeigt einen zweigeteilten Graphen, dessen Adjazenzmatrix dem Robust<br />

Soliton Distribution Schema, kurz RSD, genügt. Im linken <strong>Teil</strong> des Graphen befinden<br />

sich die Nachrichtenbits Mx, rechts die Bits des veränderten Trägermediums Ex. Um die<br />

Nachricht zurückzugewinnen geht man folgendermaßen vor:<br />

1. Finde eine Stelle mit nur einer Kante (E7)<br />

57


Abbildung 18: LT Veranschaulichung<br />

2. Setze das zugehörige Nachrichtenbit M3 gleich dem von E7<br />

3. Setze alle mit M3 verb<strong>und</strong>enen Stellen x auf x ⊕ M3 (E1 <strong>und</strong> E4)<br />

4. Streiche die zugehörigen Kanten<br />

5. Weiter mit Punkt 1., falls noch nicht alle Bits von M bestimmt sind<br />

Die Wiederherstellung der Nachricht ist in diesem Fall so einfach, weil sich durch die<br />

RSD-Beschaffenheit der Adjazenzmatrix nach Schritt 4. immer eine weitere Stelle mit nur<br />

einer Kante finden lässt, solange die Nachricht noch nicht vollständig wiederhergestellt<br />

ist.<br />

Matrix-LT-Codes Zur Lösung von Gleichung (6) wird das LT-Codes-Verfahren auf die<br />

Matrix H angewandt, um das System zu lösen. Statt eine beliebige pseudorandomisierte<br />

Matrix zu erzeugen, benutzt man eine RSD-Matrix, um damit den Rechenaufwand zu<br />

verringern.<br />

Sei wj = w(rj, rj+1, . . . , rn) das Hamming-Gewicht einer Zeile in A, dann kann A wie<br />

folgt zu einer Dreiecksmatrix umgewandelt werden:<br />

1. Setze j = 0<br />

2. Finde eine Zeile i mit wj = 1<br />

3. Setze k gleich dem Index dieser Eins im Vektor w<br />

4. Tausche Zeilen von Position i zu Position j<br />

5. Tausche Spalten von Position k zu Position j<br />

6. Setze j = j + 1<br />

7. Falls j kleiner als Zeilenanzahl von A, gehe zu Punkt 2<br />

58


Lösen der Gleichung Wendet man diese Methode auf H T in Gleichung (6) an, so ergibt<br />

sich eine neue Matrix [U, H ′ ], wobei U eine obere Dreiecks m × m Matrix mit<br />

Einsen auf der Diagonale <strong>und</strong> H ′ eine m × (k − m)-Matrix ist. Durch diese neu gewonnene<br />

Darstellungsform kann v <strong>und</strong> damit auch by durch rekursives Einsetzen berechnet<br />

werden.<br />

Einschätzung Der Kapazitätsverlust durch das Matrix-LT-Verfahren beträgt bis zu<br />

10%. Problematisch gestaltet sich die pseudorandomisierte Erzeugung einer RSD-Matrix<br />

aus dem Stego-Key [Lub02]<br />

Von Vorteil hingegen ist der niedrige Komplexitätsgrad, um das Gleichungssystem zu<br />

lösen.<br />

Perturbed Quantization (PQ) konkret Das bis hierhin beschriebene Verfahren ist allgemein<br />

gültig für beliebige Trägermedien. Perturbed Quantization im Speziellen spezifiziert<br />

als nicht defekte Zellen alle JPEG-DCT-Koeffizienten, für deren Nachkommastellen<br />

c gilt:<br />

c ∈ [0, 5 − ε; 0, 5 + ε] , ε ≤ 0, 1 .<br />

Je kleiner ε gewählt wird, desto weniger Nachrichtenbits können eingebettet werden <strong>und</strong><br />

desto geringer ist die Entdeckungswahrscheinlichkeit. PQ stört also die Quantisierung<br />

<strong>und</strong> erzeugt künstliche aber schwer zu identifizierende R<strong>und</strong>ungsfehler.<br />

Liegt das Ursprungsbild unkomprimiert vor, so kann das Verfahren direkt bei der Konvertierung<br />

in ein JPEG-Bild angewandt werden. Möchte man als Quelle ein bereits quantisiertes<br />

JPEG-Bild verwenden, so können durch Requantisierung mit einer größeren<br />

Quantiserungsmatrix künstlich Nachkommastellen erzeugt werden. Das requantisierte<br />

Bild besitzt allerdings höhere Kompressionsartefakte als das ursprüngliche.<br />

5.4 Einbettung in Rastergrafiken<br />

5.4.1 BattleSteg<br />

Zusammenfassung BattleSteg wurde von der Neuseeländerin Kathryn Hempstalk 2005<br />

entwickelt [Kat07]. Der Algorithmus ist eine Kombination aus den beiden <strong>Algorithmen</strong><br />

HideSeek <strong>und</strong> FilterFirst, die ebenfalls von dieser Autorin stammen. HideSeek basiert<br />

auf dem Programm Hide and Seek für Windows 95 <strong>und</strong> schreibt die Bits der Geheimnachricht<br />

in die LSBs von durch einen Pseudozufallsgenerator ausgewählte Pixel.<br />

FilterFirst verfolgt den Ansatz, dass Daten am besten an Kanten im Bild eingebettet<br />

werden, da hier Variationen im Farbwert nicht so auffallen wie an gleichfarbigen Flächen.<br />

Dazu wird beispielsweise ein Laplace-Filter auf das Bild angewendet. Dieser Filter berechnet<br />

für jeden Pixel einen Wert, der den Farbwertunterschied zu seinen Nachbarpixlen<br />

repräsentiert. Die Daten werden nun in Pixeln eingebettet, an denen der Filterwert hoch<br />

ist, also an dieser Stelle vermutlich eine Kante ist.<br />

BattleSteg vereint beide Ideen: Es wird ein Kantenfilter über das Bild gelegt <strong>und</strong> dann<br />

werden zufällige Kantenpixel zur Einbettung ausgewählt. Wurde ein Bit in einem Pixel<br />

eingebettet, wird, in Analogie zum Spiel Schiffe versenken, im näheren Umfeld dieses<br />

59


Pixels versucht, weitere Bits einzubetten. Nach einer Weile wählt der Algorithmus eine<br />

neue Stelle aus.<br />

Der Algorithmus ist in dem Programm Digital Invisible Ink Toolkit implementiert,<br />

welches eine Beispiel-Implementierung der Autorin ist [Kat07].<br />

Algorithmus Der Algorithmus wendet standardmäßig auf das Trägerbild einen Laplace-<br />

Filter an. Alternativ sieht das Digital Invisible Ink Toolkit auch andere Kantenfilter wie<br />

Sobel- oder Prewitt-Filter vor, welche ähnlich wie Laplace funktionieren. Als Resultat<br />

erhält man ein Kantenbild, also ein Graustufenbild, auf dem der Farbwert eines Pixels<br />

umso heller ist, je mehr er sich im Originalbild von seinen Nachbarn unterscheidet. Die<br />

Pixel dieses Filterbildes werden nun in einer Liste nach ihren Helligkeitswerten sortiert.<br />

Sind zwei Werte gleich, wird zusätzlich die x- <strong>und</strong> y-Koordinate mit einbezogen. Nun<br />

wird der Median dieser Liste gespeichert <strong>und</strong> die obersten 10% der Pixel, also die mit<br />

der stärksten Kantenausprägung, betrachtet. Diese Pixel werden als Engines bezeichnet.<br />

Nun werden die Ships gesucht. Hierzu werden die vier Nachbarpixel jeder Engine<br />

betrachtet <strong>und</strong> der Filterwert mit dem Median verglichen. Ist er grösser, wird das jeweilige<br />

Pixel als Ship markiert. Ist mindestens eins der vier Pixel ein Ship, wird auch das<br />

Engine-Pixel zu einem solchen.<br />

Listing 1: Beispielcode<br />

1 // D e f i n i e r e o b e r s t e 10% F i l t e r p i x e l<br />

2 int topten = ( int ) f i l t e r e d P i x e l A r r a y . l ength / 1 0 ;<br />

3<br />

4 // D e f i n i e r e Engines<br />

5 F i l t e r e d P i x e l e n g i n e s [ ] = new F i l t e r e d P i x e l [ topten ] ;<br />

6<br />

7 // D e f i n i e r e Median<br />

8 int median = f p a r r a y [ f i l t e r e d P i x e l A r r a y . l ength / 2 ] . g e t F i l t e r V a l u e ( ) ;<br />

9<br />

10 // D e f i n i e r e Ships<br />

11 s h i p s = new boolean [ image . getWidth ( ) ] [ image . getHeight ( ) ] ;<br />

12 for ( int i = 0 ; i < e n g i n e s . length ; i ++){<br />

13 int x = e n g i n e s [ i ] . getX ( ) ;<br />

14 int y = e n g i n e s [ i ] . getY ( ) ;<br />

15 i f (Math . abs ( f i l t e r . getValue ( x , y ) ) >= median ){<br />

16 // D e f i n i e r e P i x e l xy a l s Ship<br />

17 s h i p s [ x , y ] = true ;<br />

18 }<br />

19 }<br />

Ein Pseudozufallsgenerator, der das verwendete Passwort als Seed verwendet, wählt<br />

ein Pixel, einen Farbkanal <strong>und</strong> in diesem ein Least-Significant-Bit, welches je nach vorgegebenen<br />

Einstellungen nicht zwingend das niedrigste Bit sein muss. Diese drei Informationen,<br />

Pixel-Koordinate, Farbkanal <strong>und</strong> Bit werden zusammengenommen als Shot be-<br />

60


zeichnet. Ist das verwendete Pixel ein Ship, wird dieser Shot, also das zuvor ausgewählte<br />

Bit des Pixelfarbkanals, mit einem Bit der Geheimnachricht überschrieben.<br />

1 // Durchlaufe Nachricht<br />

Listing 2: Beispielcode<br />

2 for ( int i = 0 ; i < message . length ; i++) {<br />

3<br />

4 // Finde z u f a e l l i g e x− <strong>und</strong> y−Koordinate<br />

5 int shotx = Math . abs (Random . nextInt ( imageWidth ) ) ;<br />

6 int shoty = Math . abs (Random . nextInt ( imageHeight ) ) ;<br />

7<br />

10<br />

8 // Waehle Farbkanal<br />

9 int chanal = Math . abs (Random . nextInt ( numChanals ) ) ;<br />

11 // Waehle LSB<br />

12 int b i t p o s = mStart + Math . abs (RandomG . nextInt ( (mEnd − mStart ) + 1 ) ) ;<br />

13<br />

14 // Bette Geheimbit ein<br />

15 i f ( s h i p s [ shotx , shoty ] == true ) {<br />

16 image . s e t P i x e l B i t ( shotx , shoty , chanal , bitpos , message [ i ] ) ;<br />

17 }<br />

18 }<br />

Jetzt wendet der Algorithmus eine Technik des Spiels Schiffe versenken an, welches<br />

Namensgeber für den Algorithmus ist: Er sucht in der direkten Umgebung des eingebetteten<br />

Bits nach weiteren Stellen, an denen sich gut Daten einbetten lassen, indem<br />

er soganannte Ranged Shots zufällig plaziert, die einen vorher festgelegten Maximalabstand<br />

vom letzten Shot haben <strong>und</strong> hier weitere Bits einbettet, sollte es sich um ein Ship<br />

handeln. Nach einer ebenfalls vorher festgelegten Anzahl an Ranged Shots wird wieder<br />

ein normaler Shot durchgeführt.<br />

Um die Daten auch sicher wieder ausbetten zu können, ohne dass das erzeugte Filterbild<br />

durch das Einbetten verändert wird, wird vorher festgelegt, welche Bits eines<br />

Farbwertes der Filter betrachten soll <strong>und</strong> welche zum Einbetten benutzt werden sollen.<br />

So kann der Filter beispielsweise die ersten sechs Bit jedes Farbkanals benutzen <strong>und</strong> die<br />

letzten beiden (LS-)Bits werden zum Einbetten von Daten vorgehalten.<br />

Damit der Algorithmus beim Ausbetten weiß, wann er abbrechen muss, wird die Länge<br />

der Nachricht an deren Anfang geschrieben <strong>und</strong> mit eingebettet [Kat07].<br />

Verbesserungen Der BattleSteg-Algorithmus bietet einige Möglichkeiten zur Verbesserung.<br />

So sollte in erster Linie überprüft werden, inwiefern die sogenannten Ranged Shots<br />

überhaupt sinnvoll sind, da dadurch die eingebetteten Bits im Bild gesammelt auftreten<br />

<strong>und</strong> so möglicherweise leichter zu entdecken sind. Dies wäre beispielsweise möglich durch<br />

statische Angriffe auf Steganogramme, die mit <strong>und</strong> ohne Ranged Shots erstellt wurden.<br />

Desweiteren könnte das Finden der Ships verbessert werden. Bisher werden dafür die<br />

vier Pixel ober- <strong>und</strong> unterhalb sowie links <strong>und</strong> rechts jeder Engine in Betracht gezogen.<br />

61


1 2 3 4<br />

5 6 7 1<br />

2 3 4 5<br />

6 7 1 2<br />

Abbildung 19: Beispiel für eine 4 × 4 Gewichtsmatrix für den CPT-Algorithmus<br />

Vorstellbar wäre, alle acht angrenzenden Pixel oder sogar Pixel in einem größeren Radius<br />

in Betracht zu ziehen. Vielleicht könnte man sich so auch an Kanten ” entlanghangeln“.<br />

Zuletzt könnte die Definition der Engines verbessert werden. Statt nur die 10% hellsten<br />

Filterpixel zu verwenden könnte dieser Wert je nach Bild dynamisch festgelegt werden.<br />

5.4.2 CPT<br />

Zusammenfassung Der CPT-Algorithmus basiert auf einem im Jahre 2001 veröffentlichten<br />

Algorithmus von Y-Y.Chen, H-K. Pan <strong>und</strong> Y-C. Tseng. [YYCT01] Dieser Algorithmus<br />

wurde für die Einbettung von Daten in Schwarz-Weiß Rasterbildern, also Bildern<br />

mit 1-Bit Farbtiefe entwickelt, jedoch funktioniert er auch sehr gut auf der LSB-Ebene<br />

von mehrfarbigen Bildern.<br />

Zur Einbettung wird das Bild in Blöcke einer vorher festgelegten Größe zerlegt. Mittels<br />

einer Schlüsselmatrix <strong>und</strong> einer Gewichtsmatrix, die Sender <strong>und</strong> Empfänger des Steganogramms<br />

vorher austauschen müssen, wird in jeden Bildblock eine bestimmte Menge an<br />

Bits eingebettet. Hierbei werden allerdings immer maximal 2 Pixel pro Block verändert.<br />

Algorithmus In der folgenden Beschreibung des Verfahrens ist F das Trägerbild, m <strong>und</strong><br />

n die Dimensionen eines Bildblocks, K eine binäre Schlüsselmatrix, W eine Gewichtsmatrix.<br />

Die beiden Matrizen sind jeweils so groß wie ein Bildblock. Der Wertebereich<br />

für die Elemente der Gewichtsmatrix ist [1, 2 r − 1]. Jeder dieser Werte muss mindestens<br />

einmal vorkommen. Abbildung 19 zeigt ein Beispiel für eine solche Matrix. Es ist<br />

r ≤ ⌊log 2(mn−1)⌋ die Anzahl der Bits, die in einem Block eingebettet werden sollen <strong>und</strong><br />

Bl eine einzubettende binäre Zeichenfolge der Länge l.Der ⊕-Operator ist die elementweise<br />

XOR-Verknüpfung zweier Matrizen gleicher Größe. Mit dem ⊗-Operator werden<br />

zwei gleich große Matrizen elementweise multipliziert. Mit SUM(M) wird die Summe<br />

aller Elemente der übergebenen Matrix M berechnet.<br />

Vor dem Einbettungsvorgang wird das Bild in k Blöcke der Größe m × n aufgeteilt. In<br />

jeden Block werden r Bits eingebettet, indem mit der Vorschrift SUM((Fi⊕K)⊗W ) das<br />

Gewicht des Blockes berechnet wird <strong>und</strong> dieses dann durch Kippen von maximal zwei<br />

62


Bits innerhalb des jeweiligen Blockes an die jeweiligen Nachrichtenbits angpasst wird.<br />

Die Nachrichtenbits werden hierbei als r-stellige Binärzahl angesehen. Die zu kippenden<br />

Bits werden ermittelt, indem man die Pixel des Blockes in Mengen Sω aufteilt, deren<br />

Elemente diejenigen Pixel sind, deren Kippen das Gewicht des Blockes jeweils um ω<br />

verändert.<br />

Sω = {k, l|(Fi ⊕ K) |k,l| = 0 ∧ W |k,l| = ω ∨<br />

(Fi ⊕ K) |k,l| = 1 ∧ W |k,l| = ⌊log 2(mn − 1)⌋ − ω}<br />

Die Aufteilung in die Mengen erfolgt nach obenstehender Formel. Zusätzlich wird die<br />

Menge S0 = {∅} definiert. Mit der Differenz zwischen dem Blockgewicht <strong>und</strong> den betrachteten<br />

Nachrichtenbits d werden dann zwei Mengen Sω anhand folgender Vorschrift<br />

ausgewählt:<br />

Wähle ein h ∈ {0, 1, . . . , 2 r − 1}, so dass Sh∗d �= ∅ <strong>und</strong> S −(h−1)∗d �= ∅.<br />

Aus den beiden Mengen wird dann jeweils ein Bit ausgewählt <strong>und</strong> im Bildblock gekippt.<br />

Ist eine von den gewählten Mengen S0 hat dies zur Folge, dass nur ein Bit gekippt<br />

werden muss, um das gewünschte Blockgewicht zu erzielen.<br />

Der Vorteil dieses Verfahrens ist die konstante Einbettungsrate von ⌊log 2(m ∗ n −<br />

1)⌋ Bits pro Block <strong>und</strong> der durch die zwei Matritzen gegebene große Schlüsselraum.<br />

Außerdem ist die Änderungsrate im Vergleich zum LSB-Verfahren wesentlich geringer,<br />

da unabhängig von der Blockgröße <strong>und</strong> der Anzahl der Nachrichtenbits pro Block jeweils<br />

nur maximal zwei Bits pro Bildblock im Trägermedium verändert werden. Allerdings<br />

bettet das Verfahren die Daten sequentiell in jeden Bildblock des Trägerbildes ein. Es<br />

werden, im Gegensatz zu z.B. BattleSteg keinerlei Überprüfungen vorgenommen, ob ein<br />

bestimmter Bildblock für die Einbettung geeignet ist, oder ob diese sehr auffällig wäre,<br />

wie es z.B. bei Bildern mit größeren einfarbigen Flächen der Fall wäre. An diesem Punkt<br />

lässt sich das CPT Verfahren noch verbessern.<br />

5.5 Einbettung in Audio-Dateien<br />

5.5.1 Echo-Hiding<br />

Zusammenfassung Echo-Hiding bettet Geheiminformationen durch Einfügen eines<br />

Echos ins Audiosignale ein. Die Daten werden dabei durch den Offset (Abstand zum<br />

originalen Signal) des Echos kodiert. Wenn dieses einen sehr kleinen Abstand zum Original<br />

hat, ist es für das menschliche Ohr nicht zu erkennen. Diese Verschmelzung vom<br />

Original mit dem Echo ist vom Hörer <strong>und</strong> der Art des Trägers abhängig. Sie befindet<br />

sich bei ungefähr drei Millisek<strong>und</strong>en [FAPP99]. Das Echo fügt dem Originalton dann<br />

zusätzliche Resonanz hinzu, was allenfalls zu einem volleren Klang, im Vergleich zum<br />

Träger, führen kann.<br />

Algorithmus<br />

63


Einbettung Beim Einbetten werden von dem Träger zwei Kopien erstellt, die jeweils<br />

um ein Echo des gesamten Originalsignals angereichert werden. Die Echos der beiden<br />

Varianten haben unterschiedliche Verzögerungszeiten. Wie man in Abbildung 20 sehen<br />

kann, hat das 1-Signal einen größeren Abstand zwischen dem Original <strong>und</strong> dem Echo<br />

als das 0-Signal. Beide Verzögerungszeiten sind so gewählt, dass sie beim Hören nicht<br />

als ein Echo zu identifizieren sind.<br />

Die entstandenen Signale werden jetzt mit weich überblendenden Mischern, an-<br />

Abbildung 20: Einbettungsvorgang: 0-Signal <strong>und</strong> 1-Signal werden erstellt <strong>und</strong> den Geheimbits<br />

entsprechend gemischt.<br />

hand der zu kodierenden Geheimbits, ineinander übergeblendet. Die Mischer müssen<br />

sich an eine festgelegte Blocklänge halten, die ausreichend groß ist, um ein Echo<br />

beinhalten zu können. Diese Blocklänge legt die Einbettungsrate fest. Wie die Mischer<br />

aus den Geheimbits hervorgehen, ist auf der rechten Seite der Abbildung 20 angedeutet.<br />

Um das Signal des Steganogramms zu erhalten wird das 1-Signal mit dem 1-Mischer<br />

multipliziert <strong>und</strong> das 0-Signal mit dem 0-Mischer multipliziert. Die beiden Ergebnisse<br />

werden anschließend addiert.<br />

Extrahierung Beim Extrahieren der Geheiminformation wird das Steganogramm mittels<br />

einer Autokorrelation mit sich selbst verglichen, wodurch das Echo gef<strong>und</strong>en werden<br />

kann [auk08]. Jetzt wird durch den Abstand zwischen dem Original <strong>und</strong> dem Echo entschieden,<br />

ob das Geheimbit Null oder Eins ist.<br />

Anmerkungen Es ist nicht sichergestellt, dass durch dieses Verfahren die Geheiminformation<br />

komplett extrahiert werden kann. Je nach Eigenschaft des Trägermaterials<br />

können zum Beispiel natürliche Echos zum Problem beim Extrahieren werden. Ein<br />

64


zusätzlicher Faktor, dessen Veränderung die erfolgreiche Extrahierung verbessern kann,<br />

ist die Amplitude des Echos. Eine besonders große Amplitude des Echos führt zu einer<br />

starken Resonanzerweiterung des Steganogramms <strong>und</strong> kann, abhängig vom Audioinhalt<br />

des Trägers, auffällig sein. Als ungefährer Richtwert für eine geeignete Einbettungsrate<br />

kann 16 Bits pro Sek<strong>und</strong>e gesehen werden [DG].<br />

Da eine Extrahierung der Geheimnachrichten hier nicht gewährleistet werden kann,<br />

bietet es sich an, red<strong>und</strong>ante Daten <strong>und</strong> fehlerkorrigierende Kodierung zu benutzen.<br />

5.5.2 Phase-Coding<br />

Phase-Coding bettet Geheiminformationen durch das Verschieben von Phasen der Frequenzen<br />

eines in Audiosignals ein.<br />

Zusammenfassung Bei Phase-Coding werden die Anfangsphasen des ersten Audiosegments<br />

so gesetzt, dass diese die Geheimbits repräsentieren [Ben99]. Da die Phasen aller<br />

folgenden Segmente um diesen gesetzten Wert mitverschoben werden, entstehen keine<br />

Phasensprünge innerhalb des Audiosignals. Auf Phasensprünge reagiert das menschliche<br />

Ohr empfindlich, aber mit welcher Phase eine Frequenz beginnt, ist schwer wahrzunehmen,<br />

was beim Phase-Coding ausgenutzt wird.<br />

Algorithmus<br />

Einbettung Im Folgenden ist ω die Phase einer Frequenz.<br />

1. Der Träger wird in N Segmente unterteilt, die jeweils K Abtastwerte enthalten.<br />

2. Für jeden Index n eines Segments, wobei 0 ≤ n ≤ N − 1, wird eine diskrete<br />

Fourier-Transformation der K Abtastwerte durchgeführt. Man erhält dadurch eine<br />

Phasenmatrix Ωn(ωk) für jeden Index k einer Frequenz mit 0 ≤ k ≤ K − 1 <strong>und</strong><br />

eine Matrix Θn(θk) mit den Einträgen für die Amplitude der Frequenzen.<br />

3. Für jedes k bildet man die Phasendifferenz zweier aufeinander folgender Segmente<br />

mit den Indizes n <strong>und</strong> n + 1:<br />

∆Ωn+1(ωk) = Ωn+1(ωk) − Ωn(ωk).<br />

4. Die Geheimnachricht wird kodiert, indem man im Segment mit dem Index n = 0<br />

die Werte in der Phasenmatrix auf π<br />

π<br />

, um eine 1 zu repräsentieren, oder − , um<br />

2 2<br />

eine 0 zu repräsentieren, setzt. Man erhält also eine veränderte Phasenmatrix, die<br />

wir Φ ′ 0 nennen.<br />

5. Anhand von Ω ′ 0 können jetzt die veränderten Phasen Ω′ n für alle folgenden Segmentindizes<br />

n mit 0 < n ≤ N − 1 wie folgt berechnet werden:<br />

Ω ′ n(ωk) = ∆Ωn(ωk) + Ω ′ n−1(ωk).<br />

65


6. Mit den dadurch veränderten Phasenmatrizen Ω ′ n(ωk) <strong>und</strong> den originalen Amplitudenmatritzen<br />

Θn(θk) wird das Audiosignal durch die inverse diskrete Fourier-<br />

Transformation wieder hergestellt.<br />

Extrahierung Um die Geheimnachricht zu extrahieren, muss der Empfänger die Segmentlänge<br />

kennen <strong>und</strong> wissen, wie Geheimbits durch die Phasen repräsentiert werden.<br />

Nach einer diskreten Fourier-Transformation des Steganogramms mit der richtigen Segmentlänge<br />

kann der Empfänger anhand der Phasenmatrix des ersten Segments die Geheimnachricht<br />

ablesen.<br />

Anmerkungen Im Gegensatz zum Echo-Hiding kann die Geheimnachricht immer extrahiert<br />

werden. Phase-Coding erzeugt kein Rauschen, aber wenn zu viele Frequenzen<br />

signifikant in der Phase verschoben werden, kann es zu unerwünschten Resonanzen kommen.<br />

Daher müssen die Frequenzen <strong>und</strong> die Anzahl der Verschiebungen sinnvoll gewählt<br />

werden. Laut [Ben99] können durch dieses Verfahren 8 bis 32 Bits pro Sek<strong>und</strong>e versteckt<br />

werden, je nach Segmentlänge.<br />

5.5.3 LSB <strong>–</strong> Least Significant Bits<br />

Zusammenfassung Die Methode, Daten in den am wenigsten wichtigen Bits (Least Significant<br />

Bits, LSB) zu verstecken, ist eine der ältesten <strong>und</strong> am häufigsten anzutreffenden<br />

in der digitalen Steganographie.<br />

Algorithmus Beim LSB-Verfahren werden die Bits einer geheimen Nachricht in den<br />

untersten Bits des Covers versteckt, welche dabei überschrieben werden. Die Einbettungsrate<br />

ist zumindest theoretisch nur durch die Anzahl der überschriebenen Bits eines<br />

Coverbytes beschränkt. Werden alle Bits des Covers überschrieben, so ist das Resultat<br />

mit der Geheimnachricht identisch, <strong>und</strong> die steganographische Verarbeitung somit<br />

sinnlos.<br />

Obwohl der Ansatz, eine Nachricht in den LSBs einzubetten, vielen <strong>Algorithmen</strong> zu<br />

Gr<strong>und</strong>e liegt, unterscheiden sie sich doch durch die Auswahl der zu verändernden Bytes<br />

des Covers. Der einfachste Ansatz, vom Anfang des Covers an das unterste Bit eines<br />

jeden Bytes zu überschreiben, bis entweder die Nachricht komplett untergebracht wurde<br />

oder das Cover zu Ende ist, ist relativ leicht zu entdecken. Daher wurden <strong>und</strong> werden<br />

immer neue Methoden zur Auswahl der Trägerbytes erdacht.<br />

Die Sicherheit des verwendeten LSB-Algorithmus ist von dieser Auswahl abhängig.<br />

Wird ein sehr einfaches Schema gewählt, so ist die geheime Nachricht nicht nur einfach<br />

nachweisbar, sondern kann unter Umständen auch in der Länge abgeschätzt oder sogar<br />

extrahiert werden. Aber selbst ein sehr komplexes Einbettungsschema, wie es zum Beispiel<br />

BattleSteg (siehe Abschnitt 5.4.1) verwendet, ist nur dann vergleichsweise sicher,<br />

wenn die Einbettungsrate niedrig gehalten wird.<br />

Der große Vorteil der LSB-Methode ist der geringe Aufwand, den die Einbettung verursacht.<br />

Wählt man ein simples Einbettungsschema, ist auch der Aufwand zur Auswahl<br />

der Coverbytes sehr gering.<br />

66


Auf Audiodaten angewendet, bietet sich das WAVE-Format an, da dieses, abgesehen<br />

von einem kurzen Header am Anfang der Datei, aus einer Sammlung von 16-Bit-Zahlen<br />

besteht. Verändert man einen solchen Messwert, ein sogenanntes ”Sample”, im untersten<br />

Bit, so ändert sich die Amplitude an dieser Stelle um ein Fünf<strong>und</strong>sechzigtausendstel. Dies<br />

ist nur dann hörbar, wenn jeder Messwert genutzt wird, <strong>und</strong> auch leise Stellen in der<br />

Audiodatei überschrieben werden. Auch hier hängen die Sicherheit <strong>und</strong> der Aufwand des<br />

Algorithmus direkt vom Einbettungsschema ab.<br />

6 Verbesserungen bestehender <strong>und</strong> neue <strong>Algorithmen</strong><br />

6.1 Einbettung in Bild-Dateien<br />

6.1.1 T<br />

Zusammenfassung<br />

Im Gegensatz zu anderen <strong>Algorithmen</strong> wird keine Nachricht eingebettet, sondern davon<br />

ausgegangen, dass die Nachricht bereits in einem Träger ist. Einem Empfänger muß nur<br />

noch mitgeteilt werden, wo die Nachricht ist.<br />

Algorithmus<br />

Zunächst folgt eine kleine Einführung in Neuronale Netze<br />

Neuronale Netze<br />

Ein neuronales Netz besteht im allgemeinen aus folgenden Komponenten:<br />

• Neuronen:<br />

<strong>–</strong> Aktivierungszustand a.<br />

Dieser Zustand gibt die Aktivierung des Neurons an<br />

<strong>–</strong> Aktivierungsfunktion fact.<br />

Die Aktivierungsfunktion gibt den Aktivierungszustand aj zum Zeitpunkt t+1<br />

eines Neurons j aus dem alten Aktivierungszustand aj(t) <strong>und</strong> der Netzeingabe<br />

netj(t) an.<br />

aj(t + 1) = fact(aj(t), netj(t), θj)<br />

Wobei θj der Schwellenwert des Neurons j <strong>und</strong> fact die Aktivierungsfunktion<br />

ist.<br />

<strong>–</strong> Ausgabefunktion fout<br />

Die Ausgabe eines Neurons j, die durch eine Ausgabefunktion aus der Aktivierung<br />

des Neurons bestimmt.<br />

oj = fout(aj)<br />

• Verbindungsnetzwerk der Neuronen<br />

Ein Neuronales Netz kann als gerichteter, gewichteter Graph angesehen werden.<br />

67


Wobei die Kanten die gewichteten Verbindungen zwischen den Neuronen darstellen.<br />

Das Gewicht der Verbindung von Neuron i nach Neuron j wird als wij bezeichnet.<br />

Die Gewichtsmatrix der Verbindungen aller Neuronen wird als W bezeichnet.<br />

• Propagierungsfunktion<br />

Diese Funktion gibt an, wie sich die Netzeingabe eines Neurons aus den Ausgaben<br />

der anderen Neuronen <strong>und</strong> den Verbindungsgewichten berechnet. Die Netzeingabe<br />

netj(t) von Neuron j berechnet sich nach<br />

netj(t) = �<br />

oi(t) ∗ wij<br />

i<br />

aus der Summe der Ausgaben oi(t) der Vorgängerneuronen multipliziert mit den<br />

jeweiligen Gewichten wij der Verbindungen von Neuron i nach Neuron j.<br />

• Lernregel: Die Lernregel ist ein Algorithmus, durch die ein neuronales Netz lernt,<br />

für eine vorgegebene Eingabe eine gewünschte Ausgabe zu produzieren.<br />

BAM<br />

Ein BAM ist eine spezielle Klasse von neuronalen Netzwerken <strong>und</strong> wurde von Bart Kosko<br />

[Bar88] bekanntgemacht. Es handelt sich beim BAM um ein heteroassoziatives Netzwerk.<br />

Es akzeptiert einen Eingabevektor in einer Schicht von Neuronen <strong>und</strong> produziert einen<br />

passenden Ausgabevektor in einer anderen Schicht von Neuronen.<br />

Das BAM Netzwerk besteht aus zwei Ebenen von Neuronen, B <strong>und</strong> C. Diese zwei<br />

Schichten werden durch eine Gewichtsmatrix W von B nach C <strong>und</strong> durch eine transponierte<br />

Matrix W T von C nach B verb<strong>und</strong>en.<br />

Normalerweise wird die logistische Aktivierungsfunktion verwendet:<br />

1<br />

oi =<br />

1 + e−λ∗neti wobei oi die Ausgabe des Neurons i ist <strong>und</strong> neti die gewichtete Summe der Eingaben in<br />

Neuron i. λ ist eine Konstante, welche die Steigung der logistischen Aktivierungsfunktion<br />

bestimmt.<br />

Um das BAM für diesen Algorithmus nutzen zu können, wird eine binäre Version mit<br />

den folgenden Eigenschaften verwendet:<br />

• λ hat einen sehr großen Wert, so dass eine binäre Schwellenwertfunktion angenähert<br />

wird.<br />

• Die Neuronen können sich ihren alten Aktivierungszustand merken<br />

• Alle Ausgaben ändern sich gleichzeitig <strong>und</strong> bleiben konstant<br />

Damit ergibt sich:<br />

⎧<br />

⎪⎨ 1 wenn neti(t) > 0<br />

oi(t + 1) = 0<br />

⎪⎩<br />

oi(t)<br />

wenn neti(t) < 0<br />

wenn neti(t) = 0<br />

68


Der Schwellenwert aller Neuronen ist in diesem Modell gleich Null.<br />

Die Assoziationen des Netzwerks werden in den Gewichtsmatrizen W <strong>und</strong> W T gespeichert.<br />

Dabei wird ein Vektor X mit einem Vektor Y assoziiert <strong>und</strong> umgekehrt. Die<br />

Vektoren können dabei verschieden viele Elemente enthalten.<br />

Um nun eine gespeicherte Assoziation in einem BAM zu finden, wird wie folgt vorgegangen:<br />

• Der Vektor X wird an die Ausgabe von der Ebene B angelegt.<br />

• Daraufhin wird er wieder entfernt <strong>und</strong> das Netzwerk läuft frei mit dieser Ausgabe,<br />

wobei es durch W die assoziierte Ausgabe Y bei Ebene C erzeugt.<br />

• Diese Ausgabe erzeugt über W T in Schicht B eine zum Vektor X ähnliche Ausgabe.<br />

Dieser Prozess wird solange wiederholt bis sich das Netzwerk stabilisiert. Mit jeder Iteration<br />

werden die Ausgaben von Ebene B <strong>und</strong> C der gespeicherten Information ähnlicher.<br />

(Mathematisch betrachtet minimiert das Netzwerk eine Liapunow-Energiefunktion)<br />

Die benötigte Gewichtsmatrix für zwei Vektoren X <strong>und</strong> Y kann über<br />

W = �<br />

p<br />

X T p Yp<br />

direkt berechnet werden. W ist die Summe der äußeren Produkte der Transponierten<br />

des entsprechenden Vektors Xp mit dem Vektor Yp. Dabei gibt p jeweils ein Muster an.<br />

Um die Leistung des BAMs zu steigern werden zudem Bipolarvektoren benutzt <strong>und</strong><br />

folgende bipolare binäre Schwellenwertfunktion:<br />

⎧<br />

⎪⎨ 1 wenn neti(t) > 0<br />

oi(t + 1) = −1<br />

⎪⎩<br />

oi(t)<br />

wenn neti(t) < 0<br />

wenn neti(t) = 0<br />

JPEG<br />

Mit Hilfe eines BAM soll nun versucht werden eine geheime binäre Nachricht N in einer<br />

JPEG Grafik zu verstecken. Dazu sei angenommen, es existiert ein öffentlicher binärer<br />

Schlüssel K.<br />

Dieser Schlüssel soll nun eine Liste von Eingabevektoren mit je n Elementen darstellen.<br />

Diese Eingabevektoren Kp sollen nun mit Hilfe einer Gewichtsmatrix W mit <strong>Teil</strong>en der<br />

geheimen Nachricht Np assoziiert werden. Wobei gelten soll, dass das erste Element von<br />

K mit dem ersten Element von N usw. assoziiert wird.<br />

Die Gewichtsmatrix läßt sich nun wie folgt berechnen:<br />

W = �<br />

p<br />

K T p Np<br />

Als Beispiel sei folgender öffentlicher Schlüssel K, sowie eine geheime Nachricht N<br />

gegeben:<br />

K = (1, 0, 0, 0, 1, 0, 0, 0, 1)<br />

69


N = (0, 0, 1, 0, 1, 0, 1, 0, 0)<br />

Der Einfachheit halber sei n = 3 <strong>und</strong> die Anzahl der Elemente in Kp <strong>und</strong> Np gleich.<br />

Somit folgt:<br />

K0 = (1, 0, 0)K1 = (0, 1, 0)K2 = (0, 0, 1)K3 = (0, 1, 1)<br />

N0 = (0, 0, 1)N1 = (0, 1, 0)N2 = (1, 0, 0)N3 = (1, 0, 0)<br />

Als Bipolarvektoren dargestellt:<br />

K0 = (1, −1, −1)K1 = (−1, 1, −1)K2 = (−1, −1, 1)K3 = (−1, 1, 1)<br />

N0 = (−1, −1, 1)N1 = (−1, 1, −1)N2 = (1, −1, −1)N3 = (1, −1, −1)<br />

Die resultierende Gewichtsmatrix W ist somit:<br />

⎛ ⎞<br />

1<br />

⎛ ⎞<br />

−1<br />

⎛ ⎞<br />

−1<br />

⎛ ⎞<br />

−1<br />

W = ⎝−1⎠<br />

∗ (−1 − 11) + ⎝ 1 ⎠ ∗ (−11 − 1) + ⎝−1⎠<br />

∗ (1 − 1 − 1) + ⎝ 1 ⎠ ∗ (1 − 1 − 1)<br />

−1<br />

−1<br />

1<br />

1<br />

⎛<br />

−1 −1<br />

⎞<br />

1<br />

⎛<br />

1 −1<br />

⎞<br />

1<br />

⎛<br />

−1 1<br />

⎞<br />

1<br />

⎛<br />

−1 1<br />

⎞<br />

1<br />

= ⎝ 1 1 −1⎠<br />

+ ⎝−1<br />

1 −1⎠<br />

+ ⎝−1<br />

1 1 ⎠ + ⎝ 1 −1 −1⎠<br />

1 1 −1 1 −1 1 1 −1 −1 1 −1 −1<br />

⎛<br />

−2 0<br />

⎞<br />

4<br />

= ⎝ 0 2 −2⎠<br />

4 −2 −2<br />

Die Gewichtsmatrix besteht nur aus ganzen Zahlen, wobei das größte Element kleiner<br />

gleich p <strong>und</strong> das kleinste Element größer gleich −p ist.<br />

Wenn man sich nun einen JPEG Block, also die quantisierten Frequenzkoeffizienten<br />

eines 8x8 Pixel Blocks, als eine Matrix V vorstellt, dann ergibt sich folgendes Bild:<br />

⎛<br />

⎞<br />

DC AC1 AC2 AC3 AC4 AC5 AC6 AC7<br />

⎜ AC8 AC9 AC10 AC11 AC12 AC13 AC14 AC15⎟<br />

⎜<br />

⎟<br />

⎜AC16<br />

AC17 AC18 AC19 AC20 AC21 AC22 AC23⎟<br />

⎜<br />

⎟<br />

⎜AC24<br />

AC25 AC26 AC27 AC28 AC29 AC30 AC31⎟<br />

⎜<br />

⎟<br />

⎜<br />

⎜AC32<br />

AC33 AC34 AC35 AC36 AC37 AC38 AC39<br />

⎟<br />

⎜<br />

⎜AC40<br />

AC41 AC42 AC43 AC44 AC45 AC46 AC47<br />

⎟<br />

⎝<br />

⎠<br />

AC48 AC49 AC50 AC51 AC52 AC53 AC54 AC55<br />

AC56 AC57 AC58 AC59 AC60 AC61 AC62 AC63<br />

Wobei die Häufigkeit von Koeffizienten mit einer niedrigen Frequenz höher ist, als<br />

die mit einer hohen Frequenz. Somit ist die Wahrscheinlichkeit hoch, dass man alle<br />

Elemente einer Gewichtsmatrix in einem JPEG Block finden kann. Um eine geheime<br />

Nachricht zu übertragen, reicht es somit wenn man lediglich die Indizes der JPEG-<br />

Frequenzkoeffizienten, die für die Gewichtsmatrix notwendig sind überträgt.<br />

70


Wenn nun ein Sender die JPEG komprimierte Datei erhält <strong>und</strong> zudem die Indizes<br />

für die Gewichtsmatrix, kann er mit dem öffentlichen Schlüssel die Nachricht wieder<br />

reproduzieren:<br />

N0 = Fact(K0W )<br />

⎛<br />

−2 0<br />

⎞<br />

3<br />

N0 = Fact((1, −1, −1) ⎝ 0 2 −2⎠)<br />

4 −2 −2<br />

= Fact((−5, 0, 8)) = (−1, −1, 1)<br />

N0 = Fact(K0W T )<br />

⎛<br />

−2 0<br />

⎞<br />

4<br />

K0 = Fact((−1, −1, 1) ⎝ 0 2 −2⎠)<br />

3 −2 −2<br />

= Fact((6, −4, −3)) = (1, −1, −1)<br />

⎛<br />

−2 0<br />

⎞<br />

3<br />

N1 = Fact((1, −1, −1) ⎝ 0 2 −2⎠)<br />

4 −2 −2<br />

= Fact((−5, 0, 8)) = (−1, −1, 1)<br />

Der Zustand ist stabil, die Ausgabe, also ein <strong>Teil</strong> der Nachricht, ist (−1, −1, 1) bzw.<br />

(0, 0, 1)<br />

GIF<br />

Um nun die Indizes für die einzelnen Elemente der Gewichtsmatrix zu übertragen, sei<br />

angenommen es gibt einen öffentlichen Schlüssel K, der durchaus der selbe Schlüssel,<br />

wie für den Eingabevektor sein kann <strong>und</strong> eine GIF Grafik mit einer Farbtabelle F .<br />

⎛<br />

⎞<br />

#0000F F<br />

⎜ #F F F F 00 ⎟<br />

F = ⎜ . . . ⎟<br />

⎝ #000000 ⎠<br />

#F F F F F F<br />

Die Idee ist nun diese Farbtabelle zunächst nach Farben zu sortieren:<br />

⎛<br />

⎞<br />

#F F F F F F<br />

⎜ #F F F F 00 ⎟<br />

⎜ . . . ⎟<br />

⎝ #0000F F ⎠<br />

#000000<br />

71


Nun wird bei diesem Vektor jede Zeile ausgeblendet, deren Index in dem binären Vektor<br />

des Schlüssels K eine 0 hat.<br />

⎛ ⎞<br />

1<br />

⎜ 0 ⎟<br />

⎜<br />

⎜.<br />

. . ⎟<br />

⎝ 1 ⎠<br />

1<br />

∗<br />

⎛<br />

⎞<br />

#F F F F F F<br />

⎜ #F F F F 00 ⎟<br />

⎜ . . . ⎟<br />

⎝ #0000F F ⎠<br />

#000000<br />

=<br />

⎛<br />

⎞<br />

#F F F F F F (0)<br />

⎜ . . . ⎟<br />

⎝ #0000F F (62) ⎠<br />

#000000(63)<br />

Jetzt wird jede Farbe in diesem Vektor von 0 bis 63 durchnumeriert <strong>und</strong> die Farbtabelle<br />

des GIFs wieder so aufgebaut, daß im oberen <strong>Teil</strong> der Farbtabelle jeweils die Farben<br />

stehen, die in einem JPEG Block ein Gewichtselement darstellen. Dabei ist der Index<br />

der Farbe das Element aus dem JPEG-Block, welches in der Gewichtsmatrix an Position<br />

0 steht, das zweite an Position 2 usw. Diese Nummerierung wird dann mit einem<br />

Farbwert abgeschlossen, welches keinen Index darstellt. Da für die Gewichtsmatrix nicht<br />

alle 64 Farbeinträge benötigt werden, kann der Rest wieder für einen neuen JPEG Block<br />

genutzt werden. Ein Empfänger kann wieder diesen Algorithmus nutzen um die Indizes<br />

zu extrahieren.<br />

Kapazität<br />

Die Kapazität des Algorithmus ist durch zwei Faktoren begrenzt. Zum einen müssen die<br />

Elemente der Gewichtsmatrix in einem JPEG-Block vorhanden sein, ansonsten muß die<br />

Anzahl der Neuronen im BAM reduziert werden. Zum Anderen ist die Kapazität eines<br />

BAMs, also die Anzahl L der Vektoren die assoziiert werden können durch die folgende<br />

Formel gegeben:<br />

L < n/(2 ∗ log n)<br />

Wobei diese Grenze nur aussagt, wieviele Muster bei einer (verrauschten) Eingabe zu<br />

98% sicher erkannt werden. Da für diesen Algorithmus die Eingabe aber nicht verrauscht<br />

ist, kann diese Kapazitätsgrenze leicht überschritten werden. Somit müßte die Anzahl<br />

der Vektoren bzw. die Anzahl der <strong>Teil</strong>e aus dem Schlüssel, die mit <strong>Teil</strong>en der Nachricht<br />

assoziiert werden, immer abhängig von der Eingabe gewählt werden. Bei einer Eingabe,<br />

deren Elemente (als Vektor betrachtet) einen hohen Winkel bilden, können mehr <strong>Teil</strong>e<br />

aus Schlüssel <strong>und</strong> Nachricht assoziiert werden als bei Elementen mit kleinem Winkel.<br />

Angriff<br />

Ein Angriff auf JPEG ist nicht möglich, da hier keine Veränderung stattfindet<br />

Nur ein Angriff auf die Eigenschaften der GIF-Grafik wäre denkbar. Allerdings, unter<br />

der Annahme, dass die Farbtabelle einer GIF-Grafik willkürlich ist, sollte hier auch kein<br />

Angriff möglich sein.<br />

72


6.2 GIF<br />

6.2.1 Fortgeschrittener GIFShuffle<br />

Motivation Der GIFShuffle-Algorithmus hat eine offensichtliche Schwachstelle: Durch<br />

die stets gleiche initiale Ordnung, die sich für jedes Bild berechnen lässt, kann ein Angreifer<br />

ein durch den GIFShuffle-Algorithmus mit Informationen angereichertes Bild abfangen,<br />

die initiale Ordnung berechnen <strong>und</strong> auf die Geheimnachricht schließen.<br />

Gr<strong>und</strong>legende Funktionsweise Der GIFShuffle Algorithmus wird zweimal angewandt:<br />

Zunächst wird die initiale RGB-Ordnung hergestellt, anschließend wird diese Ordnung<br />

durch ein Passwort, das nur dem Sender <strong>und</strong> Empfänger bekannt ist, durch den<br />

GIFShuffle-Algorithmus permutiert. Die resultierende Ordnung ist nur dem Sender <strong>und</strong><br />

Empfänger bekannt <strong>und</strong> wird nun als initiale Ordnung für den GIFShuffle-Algorithmus<br />

verwendet, der die eigentliche Nachricht einbettet.<br />

Ein Angreifer kann demnach aus dem Stego-Bild nicht auf die initiale Ordnung der<br />

Nachrichteneinbettung schließen <strong>und</strong> damit die Nachricht nicht rekonstruieren, so lange<br />

er das Passwort nicht kennt.<br />

schwierig in<br />

Verbindung<br />

zu bringen<br />

RGB-Ordnung<br />

permutiere mit PW<br />

Permutation mit Passwort<br />

(nicht von Dritten abfangbar)<br />

permutiere mit Nachricht<br />

Permutation mit Nachricht<br />

Abbildung 21: Doppelte Permutation mit GIFShuffle<br />

73<br />

einfach in<br />

Verbindung<br />

zu bringen<br />

einfach in<br />

Verbindung<br />

zu bringen


6.3 Einbettung in Audio-Dateien<br />

6.3.1 WPC-Audio<br />

Zusammenfassung Die Wet-Paper-Codes aus Abschnitt 5.3.3 werden auf Audio-<br />

Dateien angewandt.<br />

Segmentierung Audio-Dateien, insbesondere unkomprimierte WAVs, sind im Allgemeinen<br />

erheblich größer als Bilder. Selbst nachdem die Komplexität des WPC-Verfahrens<br />

mittels LT-Codes reduziert worden ist, hängt der Berechnungsaufwand nicht linear von<br />

der Dateigröße. Um WPC auf Audio-Dateien anwenden zu können, müssen die Daten<br />

daher in kleinere Blöcke unterteilt werden. Die Größe dieser Blöcke kann frei gewählt<br />

werden, wobei die Geduld des Benutzers <strong>und</strong> die zu Verfügung stehende Rechenleistung<br />

die zu beachtenden Faktoren sind. Zum Wiederherstellen der versteckten Nachricht muss<br />

die gewählte Blockgröße bekannt sein.<br />

Perturbed MP3 Die Idee, die hinter Perturbed Quantization steht, kann auf<br />

MP3-Dateien übertragen werden, indem die eindimensionalen MDCT-Koeffizienten<br />

” gestört“werden. Auch bei MP3 findet vor der Huffman-Kodierung der Koeffizienten<br />

eine Quantisierung statt. Die künstlich eingefügten R<strong>und</strong>ungsfehler können hier genauso<br />

statistisch nur schwer nachgewiesen werden.<br />

Verglichen mit einem JPEG-Bild gibt es in einem durchschnittlichen MP3 wesentlich<br />

mehr Koeffizienten. Daher lassen sich entweder größere Nachrichten verstecken, oder<br />

man verkleinert das Auswahlfenster für die Koeffizienten, um statistisch unauffäligere<br />

Daten zu erzeugen.<br />

WPC-WAV<br />

Perturbed WAV Sind sowohl Quell- <strong>und</strong> Zielformat WAVs , so findet im Allgemeinen<br />

keine Quantisierung statt. Daher kann man diese auch nicht mit der obigen Methode<br />

verändern. Ein Lösungsansatz ist es, künstlich eine R<strong>und</strong>ungsoperation einzuführen,<br />

um diese dann gezielt zu stören, siehe 5.3.3. Dafür bietet sich die Umwandlung von<br />

16-Bit-PCM-Daten nach 8-Bit an. Man betrachtet dabei die unteren acht Bits als Nachkommastellen<br />

<strong>und</strong> trifft aufgr<strong>und</strong> dieser Werte eine Entscheidung, ob das betrachtete<br />

Sample modifizierbar ist oder nicht.<br />

Randomized WAV Eine einfache Veränderung der LSBs von WAV-Dateien mit pseudorandomiserten<br />

Daten, wie sie ein Verschlüsselungsalgorithmus aus der zu versteckenden<br />

Nachricht erzeugt, ist statistisch auffällig. Um die Entdeckungswahrscheinlichkeit<br />

zu verringern, kann man Wet-Paper-Codes verwenden, um die Anzahl der Samples zu<br />

reduzieren, in denen das LSB verändert wird; einfacherweise könnte diese Anzahl der<br />

Nachrichtenlänge in Bits entsprechen.<br />

Anstatt nach einem rekonstruierbaren Muster veränderbare Samples auszuwählen, kann<br />

der Sender dies zufällig tun. Ein spezieller Stego-Angriff kann also auch bei Kenntnis<br />

74


des Algorithmus die veränderten Samples nicht vorselektieren, um nur für diese die Statistik<br />

zu betrachten. Und ein allgemeiner Angriff kann aufgr<strong>und</strong> der geringen Änderung<br />

am Trägermedium keine eindeutige Entscheidung darüber treffen, ob eine Nachricht versteckt<br />

wurde oder nicht.<br />

Der gleiche Effekt kann effizienter ohne WPC erreicht werden, indem statt randomisiert<br />

pseudorandomisiert in Abhängigkeit vom Stego-Key ausgewählt wird. Dieses Verfahren<br />

wird daher nicht implementiert.<br />

6.4 Einbettung in SVG-Dateien<br />

6.4.1 SVG-Winkel<br />

Zusammenfassung Die geheime Nachricht soll in den XML-Daten eines Vektorbildes<br />

im SVG-Standard eingebettet werden. Wir vermuten, dass die Winkelangaben, wie sie<br />

bei der Beschreibung von Farbverläufen verwendet werden, sich am besten zum Einbetten<br />

von Geheimbits mittels eines LSB-Verfahrens eignen.<br />

Algorithmus Da uns kein Algorithmus bekannt ist, der die Einbettung in SVGs beherrscht,<br />

werden wir selbst einen entwickeln.<br />

Funtionsweise Die Nachkommastellen der Winkelangaben werden genutzt, um in den<br />

niedrigstwertigen Bits (den LSBs) Daten einzubetten. Da in unserem Projekt auch generische<br />

LSB-Verfahren entwickelt werden sollen, besteht die Aufgabe des konkreten SVG-<br />

Algorithmus lediglich darin, eine SVG-Datei zu lesen, die Winkeldaten (falls vorhanden)<br />

zu extrahieren <strong>und</strong> an einen der generischen LSB-<strong>Algorithmen</strong> weiter zu reichen.<br />

Ein Zwischenschritt könnte die Analyse der Winkeldaten sein, ob sie vor der Einbettung<br />

eine genügend große Zufälligkeit aufweisen. Dadurch wird verhindert, dass bei<br />

gleichmäßigen Winkeln (z.B. exakt 45 ◦ im Gegensatz zu 44, 256678371 ◦ ) die eingebetteten<br />

Daten zu stark herausstechen. In wiefern sich eine solche Analyse aber realisieren<br />

lässt, muss noch untersucht werden.<br />

Für eine Übersicht über den Aufbau eines SVGs siehe Abschnitt 4.6.<br />

Für uns von Interesse sind nicht direkt die Tags des XML-Formats, sondern das optionale<br />

Attribut transform, welches beschreibt, wie ein grafisches Element verändert wird,<br />

bevor es dargestellt wird. Dabei gibt es eine Menge verschiedener Operationen, welche<br />

innerhalb des Attributs beschrieben werden, unter anderem Rotation, Verschiebung,<br />

Verzerrung, etc. Interessant ist für uns nur die Matrix-Transformation. Eine Transformationsmatrix<br />

wird durch sechs Fließkommazahlen beschrieben, welche vergleichsweise<br />

viele Nachkommastellen <strong>und</strong> in den meisten Fällen eine hohe Entropie aufweisen.<br />

Das transform-Attribut zur Matrixbeschreibung kommt in einem SVG nicht<br />

sehr häufig zum Einsatz. Dafür wird aber umso häufiger das gradientTransform-<br />

Attribut genutzt, um die Transformation eines Farbverlaufs ( oder<br />

) anzugeben.<br />

75


Aufwand, Einbettungsrate <strong>und</strong> Sicherheit Von dem reinen Extrahieren <strong>und</strong> der<br />

eventuellen Analyse der Winkeldaten einmal abgesehen, entsprechen Aufwand, Einbettungsrate<br />

<strong>und</strong> Sicherheit des Algorithmus denen des verwendeten generischen LSB-<br />

Algorithmus.<br />

Die Herausforderung beim Extrahieren der Coverbytes wird es sein, die Fließkommazahlen<br />

auf eine ähnliche Art zu behandeln wie die ganzzahligen Werte der bisherigen<br />

LSB-Anwendungsfälle.<br />

6.5 Einbettung in PDF-Dateien<br />

6.5.1 PDFShuffle<br />

Zusammenfassung<br />

Ähnlich wie bei der Umsortierung der Farbtabelle von GIF Grafiken, können auch die<br />

einzelnen Objekte eines PDF Dokuments umsortiert werden.<br />

Algorithmus<br />

Vor der allgemeinen Beschreibung des PDF Formats, soll kurz auf die innere Struktur<br />

eingegangen werden. Ein PDF Dokument besteht aus einzelnen Objekten. Diese werden<br />

über einen Katalog bzw. XREF Tabelle referenziert. Durch diese baumartige Struktur<br />

Abb.22 kann ein PDF-Reader schnell eine bestimmte Seite in einem Dokument anzeigen,<br />

ohne dieses erst ganz einlesen zu müssen. Besonders interessant für diesen Algorithmus,<br />

Lesezeichen<br />

Catalog<br />

Seite 1<br />

Seite 2<br />

Seite 3<br />

Abbildung 22: PDF-Struktur<br />

Artikel<br />

ist die XREF Tabelle <strong>und</strong> die Anordnung der Objekte. Ein XREF Eintrag ist 20 Bytes<br />

lang, die ersten 10 Bytes geben den Offset innerhalb des PDF-Stroms an. Daraufhin folgt<br />

ein Leerzeichen <strong>und</strong> die 5 Bytes lange Generationsnummer. Den Abschluß bildet wieder<br />

ein Leerzeichen gefolgt von der Kennzeichnung des Objekts. Diese besteht entweder<br />

aus dem Buchstaben n für inuse entry (vorhandene Objekte) oder f für free entry<br />

(gelöschte Objekte). Die letzten 2 Bytes können entweder ein CRLF Zeilenumbruch<br />

76


oder ein Leerzeichen gefolgt von CR oder LF sein.<br />

Das folgende Beispiel zeigt ein einfaches PDF Dokument:<br />

%PDF-1.2<br />

1 0 obj<br />

><br />

stream<br />

60 5 m<br />

110 5 l<br />

85 45 l<br />

.5 .6 1 rg<br />

f<br />

21 5 m<br />

44 32 87 37 115 17 c<br />

3 w<br />

0 G<br />

S<br />

.707 .707 -.707 .707 0 0 cm<br />

BT<br />

/F1 9 Tf<br />

10 -5 Td<br />

.9 .3 .3 rg<br />

(Hello World!) Tj<br />

ET<br />

endstream<br />

endobj<br />

2 0 obj<br />

><br />

endobj<br />

3 0 obj<br />

><br />

/Contents 1 0 R<br />

>><br />

endobj<br />

77


4 0 obj<br />

><br />

endobj<br />

5 0 obj<br />

><br />

endobj<br />

xref<br />

0 6<br />

0000000000 65535 f<br />

0000000009 00000 n<br />

0000000215 00000 n<br />

0000000296 00000 n<br />

0000000467 00000 n<br />

0000000530 00000 n<br />

trailer<br />

< /Size 6 /Root 5 0 R >><br />

startxref<br />

582<br />

%%EOF<br />

Im unteren <strong>Teil</strong> befindet sich die XREF Tabelle, die den Offset für jedes Objekt innerhalb<br />

des Dokuments enthält. Bei kleinen Dokumenten ist diese Tabelle meist aufsteigend<br />

sortiert, da das erste Objekt meist auch die erste Seite darstellt. Allerdings können nach<br />

[Ado08b] beliebige Objekte eingefügt bzw. auch gelöscht werden. Beim löschen werden<br />

allerdings die Objekte nicht aus dem Dokument entfernt, sondern nur die Kennzeichnung<br />

von n auf f geändert. Somit kann davon ausgegangen werden, dass bei großen Dokumenten<br />

keine Sortierung der XREF Tabelle mehr herrscht. In einem solchen Fall kann<br />

der GIF Shuffle Algorithmus auf die Objekte eines PDF Dokuments angewendet werden.<br />

Wobei die einzelnen Objekte die Rolle der Farbtabelle einer GIF-Grafik übernehmen.<br />

Analyse von Format <strong>und</strong> Algorithmus<br />

Damit PDFShuffle effizient eingesetzt werden kann, muss sichergestellt werden, dass eine<br />

Vielzahl von PDF-Dokumenten genügend Objekte bietet, um eine hohe Einbettungsrate<br />

zu erreichen, als auch, dass die Entdeckungswahrscheinlichkeit nicht höher ist als die von<br />

GIFShuffle.<br />

Es wurde daher ein Programm entwickelt, das mit Hilfe der Yahoo-Search-Engine<br />

PDF-Dateien herunterlädt <strong>und</strong> analysiert, um eben genannte Anforderungen empirisch<br />

zu testen. Es wurden in drei Durchläufen jeweils 5000 unterschiedliche PDF-Dateien<br />

78


getestet:<br />

Test 1:<br />

• Objekte insgesamt: 1492059<br />

• nicht linear angeordnet insgesamt: 115223<br />

• nicht linear angeordnet <strong>und</strong> dabei als gelöscht markiert: 493964<br />

• linear angeordnet <strong>und</strong> dabei als gelöscht markiert: 1906<br />

• Im Schnitt 298.4118 Klassen pro Datei<br />

• Im Schnitt 121.8374 nicht sortierte Klassen pro Datei (40.8286133457 %)<br />

• davon als geloescht markierte: 98.7928 nichtsortierte Klassen pro Datei<br />

(81.0857749755 %)<br />

• Im Schnitt 0.3812 als geloescht markierte aber sortierte Klassen pro Datei<br />

Test 2:<br />

• Objekte insgesamt: 1720354<br />

• nicht linear angeordnet insgesamt: 213347<br />

• nicht linear angeordnet <strong>und</strong> dabei als gelöscht markiert: 522780<br />

• linear angeordnet <strong>und</strong> dabei als gelöscht markiert: 10045<br />

• Im Schnitt 344.0708 Klassen pro Datei<br />

• Im Schnitt 147.2254 nicht sortierte Klassen pro Datei (42.7892747655 %)<br />

• davon als geloescht markierte: 104.556 nichtsortierte Klassen pro Datei<br />

(71.0176369023 %)<br />

• Im Schnitt 2.009 als geloescht markierte aber sortierte Klassen pro Datei<br />

Test 3:<br />

• Objekte insgesamt: 242597<br />

• nicht linear angeordnet insgesamt: 13712<br />

• nicht linear angeordnet <strong>und</strong> dabei als gelöscht markiert: 6783<br />

• linear angeordnet <strong>und</strong> dabei als gelöscht markiert: 357<br />

• Im Schnitt 48.5194 Klassen pro Datei<br />

• Im Schnitt 4.099 nicht sortierte Klassen pro Datei (8.4481671249 %)<br />

79


• davon als geloescht markierte: 1.3566 nichtsortierte Klassen pro Datei<br />

(33.0958770432 %)<br />

• Im Schnitt 0.0714 als geloescht markierte aber sortierte Klassen pro Datei<br />

Die Tests zeigen, dass die allermeisten Objekte, die nicht linear angeordnet sind, als<br />

gelöscht markiert sind. Eine Einbettung in alle Objekte würde daher im Gegensatz zu<br />

GIFShuffle zwar eine bessere Einbettungsrate aber auch eine deutlich höhere Entdeckungswahrscheinlichkeit<br />

bedeuten. Eine Einbettung in die als gelöscht markierten Objekte<br />

einer PDF-Datei wäre beinahe eben so sicher wie die Einbettung in GIF-Dateien,<br />

die Einbettungsrate würde aber im Schnitt auf log2(100!) sinken.<br />

Der letzte Test zeigt weiterhin, dass im Internet viele PDF-Dateien zu finden sind, die<br />

sich für eine Einbettung wegen ihre Größe nicht eignen würden, da zu wenige Objekte<br />

vorhanden sind.<br />

Die <strong>Projektgruppe</strong> hat sich deshalb dagegen entschieden, den Algorithmus PDFShuffle<br />

in die Softwarebibliothek aufzunehmen.<br />

6.6 Einbettung in CSS-Dateien<br />

6.6.1 CSS-Steganographie<br />

Zusammenfassung CSS bietet die Möglichkeit, Informationen sowohl durch Permutation<br />

von Eigenschaft-Werte-Paaren als auch mittels Leerzeichen zu verstecken.<br />

Algorithmus Analog zu GIF-Shuffle wird für alle Eigenschaften eine natürliche Ordnung,<br />

beispielsweise die alphabetische, definiert. Innerhalb eines Selektors können durch<br />

Permutation dieser Reihenfolge ca log 2 n! Bits versteckt werden.<br />

Um die Kapazität des Trägermediums zu erhöhen, werden durch Hinzufügen oder Weglassen<br />

von Leerzeichen Nullen <strong>und</strong> Einsen codiert.<br />

CSS eignet sich für diese beiden Verfahren gut, da ein solches Stylesheet normalerweise<br />

’natürlich wächst’; vom Autor einer Website werden hier Informationen ohne<br />

erkennbares System hinzugefügt oder entfernt, weshalb die zufällige Reihenfolge der<br />

Eigenschaft/Werte-Paare statistisch nicht auffällig ist.<br />

Analyse von Format <strong>und</strong> Algorithmus Die Untersuchung von 13000 im Internet verwendeten<br />

CSS-Dateien zeigte, dass eine Implementierung dieses Algorithmus nicht lohnenswert<br />

ist. Im Schnitt enthielten die Dateien 62 Klassen. Wird der Shuffle-Algorithmus<br />

angewendet auf die Klassen einer CSS-Datei so ergibt sich eine Einbettungsrate von<br />

log 2 62! = 284 Bits.<br />

Eine Einbettung durch Verwendung von Leerzeichen erwies sich als sehr auffällig,<br />

wodurch die erwartete Einbettungsrate von log 2 n!) + n nicht erreicht werden kann. Um<br />

die Einbettungsrate anzuheben könnte zusätzlich in die Attribute eingebettet werden. Da<br />

eine Klasse durchschnittlich nur zwei Attribute enthält, könnte man hier gerade einmal<br />

62 Bits einbetten. Damit läge die zu erwartende Einbettungsrate bei 346 Bits.<br />

Unter diesen Umständen wird eine Implementierung nicht in Betracht gezogen.<br />

80


7 Die Bibliothek libstego<br />

Die hier vorgestellten <strong>Algorithmen</strong> <strong>und</strong> Mechanismen der Steganographie sind bisher<br />

häufig nur als einzelne Implementierungen zu finden. Steganographische Software ist<br />

nicht weit verbreitet, <strong>und</strong> es fehlt eine gemeinsame Gr<strong>und</strong>lage für die erhältliche Software.<br />

Ziel dieser <strong>Projektgruppe</strong> ist es, eine Bibliothek zu entwickeln, welche die Entwicklung<br />

von steganographischen Programmen ermöglicht, ohne dass jeder Entwickler die <strong>Algorithmen</strong><br />

neu implementieren muss. Die genauen Funktionen der Bibliothek werden in<br />

späteren Dokumenten vorgestellt, hier wird zunächst nur unsere Motivation dargelegt<br />

<strong>und</strong> ein grober Überblick über den geplanten Aufbau geliefert.<br />

7.1 Aufbau der Bibliothek<br />

Während der Planung der Bibliothek haben wir uns entschieden, Funktionen zum Einlesen<br />

<strong>und</strong> Schreiben bestimmter Dateiformate in eine gesonderte Bibliothek zu verschieben,<br />

um uns in der Kernbibliothek auf die <strong>Algorithmen</strong> konzentrieren zu können. Beide Bibliotheken<br />

kommunizieren über noch festzulegende Datenstrukturen miteinander. Durch<br />

die Trennung von Datei-Ein- <strong>und</strong> -Ausgabe von den eigentlichen Berechnungen können<br />

Anwender unserer Bibliothek auch eigene Dateiformate verwenden, die sie direkt an die<br />

<strong>Algorithmen</strong> übergeben können.<br />

7.2 Implementierungsdetails<br />

Als Programmiersprache wurde C gewählt, da es als der kleinste gemeinsame Nenner<br />

für die Entwicklung von Bibliotheken angesehen wurde. Eine in C implementierte Bibliothek<br />

kann in einer Vielzahl von anderen Programmiersprachen verwendet werden,<br />

der umgekehrte Fall ist weniger häufig. Außerdem gilt C als performant <strong>und</strong> bietet gute<br />

Möglichkeiten zur direkten Manipulation von Bits, was für viele der <strong>Algorithmen</strong> wichtig<br />

ist.<br />

Für die Ein- <strong>und</strong> Ausgabe der verschiedenen Dateitypen werden wir bereits vorhandene<br />

Bibliotheken verwenden, soweit dies möglich ist. Ebenfalls werden wir spezielle<br />

mathematische Bibliotheken verwenden, um den Implementierungsaufwand im Rahmen<br />

<strong>und</strong> den Fokus auf den steganographischen <strong>Algorithmen</strong> zu halten.<br />

81


Glossar<br />

Alphakanal Ein zusätzlicher Farbkanal, der jedoch nicht eine Farbe aus RGB, sondern<br />

den Transparenzwert eines Pixels beschreibt.<br />

big-endian Bezeichnet die Reihenfolge in der Bytes für das Speichern von Zahlen abgelegt<br />

werden. Diese Reihenfolge ist wichtig, wenn mehr als ein Byte nötig ist, um<br />

einen Zahlenwert zu repräsentieren. Bei der big-endian Reihenfolge wird das Byte<br />

mit den höchstwertigen Bits zuerst gespeichert..<br />

Containerformat Als Containerformat bezeichnet man ein Dateiformat, das verschiedenartige<br />

Datenformate enthalten kann. Das Containerformat legt dabei nur die<br />

Art <strong>und</strong> Struktur fest, wie der Inhalt abgelegt wird..<br />

Cover Ein Medium, in das eine Geheimnachricht eingefügt werden soll.<br />

DCT Abkurzung fur ” Diskrete Kosinus Transformation “.<br />

Dichtefunktion Die Wahrscheinlichkeitsdichte ist ein Hilfsmittel, mit dem sich die Wahrscheinlichkeit<br />

berechnen lässt, dass eine stetige Zufallsvariable zwischen zwei reellen<br />

Zahlen a <strong>und</strong> b liegt..<br />

Entropie Mittlerer Informationsgehalt eines Zeichens.<br />

Entropiekodierung Kompressionsverfahren, in dem haufig vorkommende Zeichen mit<br />

weniger Bits kodiert werden als seltene. Bekannteste Vertreter sind Huffman-<br />

Kodierung <strong>und</strong> Arithmetische Kodierung.<br />

F5 Steganographischer Algorithmus von Andreas Westfeld.<br />

Gamma Mittels Gammakorrektur wird die Helligkeit von Bildern an verschiedene Ausgabegerate<br />

angepasst..<br />

Hamming-Gewicht ist die Anzahl an Einsen in einem binaren Vektor..<br />

Hammingdistanz Maß für die Unterschiedlichkeit von zwei Zeichenketten.<br />

Huffman-Codes Kompressionsverfahren, das unter anderem im Grafikformat PNG verwendet<br />

wird.<br />

ISO International Organization for Standardization, eine internationale Organisation<br />

zum Definieren von Standards.<br />

JFIF Konkretes Dateiformat, das JPEG benutzt.<br />

JPEG Verfahren zur verlustbehafteten Kompression von Bildern.<br />

82


JPEG-2000 Weiterentwicklung des JPEG-Standards von 1992.<br />

Laplace-Filter Bildfilter zum Auffinden von Kanten in einem Bild.<br />

LSB Das LSB ist das niederwertigste Bit eines binären Strings.<br />

LZW-Algorithmus Lempel-Ziv-Welch-Algorithmus zur Kompression, der im Bildformat<br />

GIF verwendet wird.<br />

Matrixkodierung Verfahren zur Einbettung von Nachrichtenbits in Kodewörtern.<br />

MBS Modellbasierte Steganographie.<br />

Palettengrafik Grafik, in der die Farbwerte in einer Palette gespeichert sind <strong>und</strong> die<br />

Pixeldaten lediglich Indizes der Palette speichern.<br />

PCM Die Puls-Code-Modulation ist ein Verfahren, das genutzt wird, um ein analoges<br />

Signal in ein digitales Signal umzuwandeln..<br />

Permutative Spreizung Einbettungskoeffizienten werden mit Hilfe einer Permutation<br />

ausgewählt.<br />

PQ Perturbed Quantization ist ein Verfahren, um Nachrichten in JPEGs zu verstecken..<br />

Prewitt-Filter Bildfilter zum Auffinden von Kanten in einem Bild, ahnlich LaPlace.<br />

Random Seed Eine Bytefolge, die einen Zufallsgenerator speist, so dass die generierten<br />

Werte auf Sender- <strong>und</strong> Empfängerseite gleich sind.<br />

Rastergrafik Grafik, in der jedes Pixel mit einer bestimmten, formatabhängigen Anzahl<br />

Bits den Farbwert <strong>und</strong> ggf. Transparenzwert beschreibt.<br />

RSD Eine Matrix, die dem Robust Soliton Distribution Schema genugt, kann leicht in<br />

eine Dreiecksform gebracht werden.<br />

Sample Einzelner Messwert, im Zusammenhang mit dem WAVE-Audiodateiformat ein<br />

Messwert, der die Amplitude des Signals zu einem bestimmten Zeitpunkt angibt..<br />

Sobel-Filter Bildfilter zum Auffinden von Kanten in einem Bild, ahnlich LaPlace.<br />

Stego-Bild Ein Bild, in das eine Geheimnachricht eingebettet worden ist.<br />

Stego-Key Ein Schlüssel oder Passwort, der/das als Random Seed verwendet wird.<br />

SVG Scalable Vector Graphic, ein XML-basiertes Format zum Speichern von Vektorbildern..<br />

Tag Ein Tag erweitert die Daten in einer Datei um Zusatzinformation, beispielsweise<br />

deren Ursprung oder wie die Daten interpretiert werden sollen..<br />

83


Tagged File Format Ein Dateiformat, dass über standardisierte Tags angibt in welcher<br />

Form <strong>und</strong> Länge die Daten vorliegen..<br />

W3C World Wide Web Consortium, eine internationale Organisation für Web-<br />

Standards.<br />

WPC Wet-Paper-Codes sind eine Methode, um Nachrichten effizient zu verstecken.<br />

XML Extensible Markup Language, ”[. . . ]eine Auszeichnungssprache zur Darstellung<br />

hierarchisch strukturierter Daten in Form von Textdateien.”??.<br />

XOR Binäre Operation, die nur dann wahr wird, wenn genau einer der beiden Operanden<br />

wahr ist..<br />

YCbCr Farbmodell, welches Farben in einen Helligkeitsanteil (Luminanz Y) <strong>und</strong> zwei<br />

Farbarten (Chrominanz Cb <strong>und</strong> Cr) aufteilt.<br />

84


Literatur<br />

[Ado06] Adobe Systems Incorporated. PDF Reference, sixth edition. http://www.<br />

adobe.com/devnet/pdf/pdf_reference.html, November 2006.<br />

[ado08a] Adobe.com. http://www.adobe.com, Juni 2008.<br />

[Ado08b] Adobe. PDF Reference and Related Documentation. http://www.adobe.<br />

com/devnet/acrobat/pdfs/pdf_reference.pdf, Juni 2008.<br />

[auk08] Autokorrelation. http://de.wikipedia.org/wiki/Autokorrelation, Juni<br />

2008.<br />

[Bar88] Bart Kosko. Bidirectional Associative Memories. IEEE Transactions on<br />

Systems, Man and Cybernetics,, 18(1):49<strong>–</strong>60, 1988.<br />

[Ben99] Walter Bender. Techniques for data hiding. http://www.research.ibm.<br />

com/journal/sj/353/sectiona/bender.html, Juli 1999.<br />

[Blo08] Blooberry. CSS Properties. http://www.blooberry.com/indexdot/css/<br />

propindex/all.htm, August 2008.<br />

[Bol07] Boll, Susanne. Vorlesung Medienverarbeitung, Mai 2007.<br />

[Bol08] Boll, Susanne. Vorlesung Internet Technologien, Januar 2008.<br />

[Bra94] Brani Vidakovic, Peter Mueller. Wavelets For Kids. http://www2.isye.<br />

gatech.edu/~brani/wp/kidsA.pdf, December 1994.<br />

[BW04] Rainer Böhme and Andreas Westfeld. Breaking Cauchy Model-Based JPEG<br />

Steganography with First Order Statistics. 2004.<br />

[Cra98] Ron Crandall. Some Notes on Steganography. Gesendet an die Steganography<br />

Mailing List. 1998.<br />

[Deu96] Peter Deutsch. Deflate compressed data format specification version 1.3.<br />

http://tools.ietf.org/html/rfc1951, 1996.<br />

[DG] Walter Bender Daniel Gruhl, Anthony Lu. Echo Hiding. http://www.media.<br />

mit.eduzSzDataHidingzSzedh2.pdf/gruhl96echo.pdf.<br />

[FAPP99] Markus G. Kuhn Fabien A. P. Petitcolas, Ross J. Anderson. Information<br />

Hiding—A Survey. http://www.cl.cam.ac.uk/~rja14/Papers/<br />

ieee99-infohiding.pdf, Juli 1999.<br />

[FGH03] Jessica J. Fridrich, Miroslav Goljan, and Dorin Hogea. Steganalysis of JPEG<br />

Images: Breaking the F5 Algorithm. In IH ’02: Revised Papers from the 5th<br />

International Workshop on Information Hiding, pages 310<strong>–</strong>323, London, UK,<br />

2003. Springer-Verlag.<br />

85


[Fou08] FourCC Org. Video Codes and Pixelformat Definitions. http://www.<br />

fourcc.org, Mai 2008.<br />

[Fri05a] Fridrich J., Goljan M., Soukal D. Efficient Wet Paper Codes, 2005.<br />

[Fri05b] Fridrich J., Goljan M., Soukal D. Perturbed Quantization Steganography,<br />

2005.<br />

[GIFa] http://www.gnu.org/philosophy/gif.html.<br />

[GIFb] http://progfree.org/Patents/Gif/origCompuServe.html.<br />

[GIFc] http://www.w3.org/Graphics/GIF/spec-gif89a.txt.<br />

[IHWC87] Radford M. Neal Ian H. Witten and John G. Cleary. Arithmetic coding for<br />

data compression. Commun. ACM, 30(6):520<strong>–</strong>540, 1987.<br />

[ISO92a] ISO , ITU. JPEG Specification. http://www.iso.org/iso/iso_catalogue/<br />

catalogue_tc/catalogue_detail.htm?csnumber=18902, 1992.<br />

[ISO92b] ISO , ITU. JPEG Specification. http://www.itu.int/rec/T-REC-T.<br />

81-199209-I/en, 1992.<br />

[ISO00] ISO , ITU. JPEG-2000 Part 1. http://www.jpeg.org/public/<br />

15444-1annexi.pdf, 2000.<br />

[Jir01] Jiri Fridrich, Du Rui. Secure Steganographic Methods for Palette Imagages.<br />

Proceedings ACM, Workshop on Multimedia & Security, 2001.<br />

[Joh] Corinna John. Steganography 14 - what text lists, gif images, and<br />

html pages have in common. http://www.codeproject.com/KB/security/<br />

steganodotnet14.aspx.<br />

[Kat07] Kathryn Hempstalk. Digital Invisible Ink Toolkit. http://diit.<br />

sourceforge.net/, September 2007.<br />

[Lub02] Luby Michael. LT Codes. In Proc. The 43rd Annual IEEE Symposium on<br />

Fo<strong>und</strong>ations of Computer Science, pages 271<strong>–</strong>282, November 2002.<br />

[MA99] Thomas Boutell et alii Mark Adler. Portable network graphics (png) specification,<br />

version 1.2. http://png.unicast.org/pub/png/spec/1.2/, Juli<br />

1999.<br />

[pcm08] WAVE PCM so<strong>und</strong>file format. http://ccrma.stanford.edu/CCRMA/<br />

Courses/422/projects/WaveFormat/, Juni 2008.<br />

[Roe] Greg Roelofs. Portable network graphics. http://www.libpng.org/pub/<br />

png/.<br />

86


[Sal05] Phil Sallee. Model-Based Methods For Steganography And Steganalysis. Int.<br />

J. Image Graphics, 5(1):167<strong>–</strong>190, 2005.<br />

[Ter84] Terry A. Welch. A Technique for High-Performance Data Compression.<br />

http://www.cs.duke.edu/courses/spring03/cps296.5/papers/<br />

welch_1984_technique_for.pdf, 1984.<br />

[W3C08a] W3C. CSS. http://www.w3.org/Style/CSS/, August 2008.<br />

[W3C08b] W3C. CSS Selektoren. http://www.w3.org/TR/css3-selectors/<br />

#selectors, August 2008.<br />

[Wes01] Andreas Westfeld. F5-A Steganographic Algorithm. In IHW ’01: Proceedings<br />

of the 4th International Workshop on Information Hiding, pages 289<strong>–</strong>302,<br />

London, UK, 2001. Springer-Verlag.<br />

[Wik08a] Wikipedia. Arithmetisches Kodieren. http://de.wikipedia.org/wiki/<br />

Arithmetisches_Kodieren, Mai 2008.<br />

[Wik08b] Wikipedia. Cascading Style Sheets. http://de.wikipedia.org/wiki/<br />

Cascading_Style_Sheets, Juni 2008.<br />

[Wik08c] Wikipedia. Huffman-Code. http://de.wikipedia.org/wiki/<br />

Huffman-Kodierung#Huffman-Code, Mai 2008.<br />

[Wik08d] Wikipedia. JFIF. http://de.wikipedia.org/wiki/JFIF, Mai 2008.<br />

[Wik08e] Wikipedia. JPEG. http://de.wikipedia.org/wiki/JPEG, Mai 2008.<br />

[Wik08f] Wikipedia. JPEG-2000. http://de.wikipedia.org/wiki/JPEG-2000, Mai<br />

2008.<br />

[Wik08g] Wikipedia. Scalable Vector Graphics. http://de.wikipedia.org/wiki/<br />

SVG, Juni 2008.<br />

[Wik08h] Wikipedia. YCbCr-Farbmodell. http://de.wikipedia.org/wiki/<br />

YCbCr-Farbmodell, Mai 2008.<br />

[wp08] Wikipedia Artikel: Portable Document Format. http://de.wikipedia.org/<br />

wiki/Pdf, Juni 2008.<br />

[wpw08] Wikipedia Artikel: RIFF WAVE. http://de.wikipedia.org/wiki/RIFF_<br />

WAVE, Juni 2008.<br />

[YYCT01] H-K. Pan Y-Y. Chen and Y-C. Tseng. A secure data hiding scheme for<br />

two-color images. IEEE Symposium on Computers and Communication<br />

(ISSC2000), 2001.<br />

87

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!