Projektgruppe STEGO: Theoretischer Teil – Formate und Algorithmen
Projektgruppe STEGO: Theoretischer Teil – Formate und Algorithmen
Projektgruppe STEGO: Theoretischer Teil – Formate und Algorithmen
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