Kryptologie
One-Time-Pad mit Clifford Attraktor
Es geht in diesem Kapitel um zwei Dinge: Wie kann man in Processing auf Bit-Ebene die XOR Verknüpfung darstellen
und wie erzeugt man mit Hilfe des
Clifford Attraktore ein
One-Time-Pad ?
Ein One-Time-Pad ist ein "Einmalschlüsselung-Verfahren", das eine Schlüssel verwendet, der mindestens so lange ist,
wie die Nachricht. Mit einem Schlüssel, der echt zufällig ist und auch nur ein einziges Mal verwendet wurde,
kann die Nachricht nicht entschlüsselt werden. Das ist keine Vermutung: Es ist mathematisch beweisbar!
Wer es genauer wissen will, schaut
hier nach.
Der Haken an der Sache: Es ist nicht einfach, einen wirklich zufälligen Schlüssel zu erzeugen! Eine Methode wäre,
radioaktiven Zerfall zu verwenden. Hat man bei einer radioaktiven Probe festgestellt, dass mit 50%-iger Wahrscheinlichkeit
zehn Teilchen innerhalb einer Sekunde zerfallen, dann wählt man 1, falls dies zutrifft und 0 in gegenteiligen Fall.
Mühsam! Man sucht daher Funktionen, die dem Zufall nahe kommen. Die einfachste ist random() in Java und Processing.
Leider ist sie in keinster Weise sicher. Deutlich besser ist die Methode SecureRandom(), die aktuelle Daten des Betriebssystems
mit verwendet.
Wir benutzen eine Variante des chaotischen Clifford Attraktors.
Man erzeugt damit eine komplizierte Menge fraktalen Charakters. Das chaotische System erzeugt man durch
genügend lange Iterationen der dynamischen Clifford Iteration.
Wie die Abbildung genau aussieht, lesen Sie dort im Abschnitt Clifford Gleichungen als partielle Ableitungen interpretiert .
Eine wesentliche Eigenschaft, die die Abbildung haben sollte, ist eine hohe Empfindlichkeit (sensitivity) von den Parametern,
die als Schlüssel dienen. Genau das aber ist bei chaotischen Abbildungen der Fall. In unserem Fall wird es fünf achtstellige
Parameter geben. Falls nur eine der 40 Ziffern verändert wird, ist keine (auch teilweise) Entschlüsselung mehr möglich.
Zudem sollten die, durch die Clifford Abbildung erzeugten möglichen Ergebnisse, gleichverteilt sein. Dies ist, wie
wir sehen werden, ebenfalls erfüllt. Es ist bei chaotischen Abbildungen gänzlich unmöglich, einen Folgewert aus
den vorhergehenden zu bestimmen, ohne den Algorithmus und die Paramter genau zu kennen .
Zur XOR Verknüpfung auf Bit-Ebene:
Zunächst bestimmen wir auf übliche Weise zwei Zufallsfarben (farbe1,farbe2) und bringen sie in ihre Einzel-Bit Darstellung.
int a = int(alpha(farbe1)) << 24;
int r = int(red(farbe1)) << 16;
int g = int(green(farbe1)) <<8;
int b = int(blue(farbe1));
int A = int(alpha(farbe2)) << 24;
int R = int(red(farbe2)) << 16;
int G = int(green(farbe2)) << 8;
int B = int(blue(farbe2));
farbeBin1 = a | r | g | b;
farbeBin2 = A | R | G | B;
Bedenken Sie, dass im RGB-Mode 32 Bit für eine Farbe samt Transparenz (alpha) benötigt werden. Von links nach rechts
kommen erst 8 Bit für den Alphawert, dann 8 Bit für rot, dann 8 Bit für grün und schließlich 8 Bit für blau.
Die erste Zeile bedeutet: Schiebe die acht Bit des Alphawerts a ganz nach vorn und ergänze durch 24 Bit
mit Wert 0. Ohne Transparenz ist a =255 oder 11111111, insgesamt also 11111111 00000000 00000000 00000000.
Für beispielsweise r = 17 oder 0010001, erhält man den Eintrag der 8 Bit vor der 16.Stelle: 00000000 00100001 00000000 00000000.
Der senktrechte Strich "|" bei farbeBin1 ist die
OR-Verknüpfung. Es gilt: 0 | 0 = 0 und 1 für alle andern
Möglichkeiten. In unserem Beispiel wäre daher a | r :
11111111 00000000 00000000 00000000
00000000 00100001 00000000 00000000
11111111 00100001 00000000 00000000
Nach der Zeile
farbeBin1 = a | r | g | b haben alle Bits ihren der Farbe entsprechenden Wert.
Mit
fill(farbeBin1) kann
man das obere Quadrat einfärben. Entsprechend verfährt man beim 2. Quadart.
Die
XOR-Verknüpfung (ausschließendes oder) ist definiert durch: 0 | 0 = 0 und 1 | 1 = 0. Bei
verschiedenen Bit-Werten erhält man 1. So funktioniert die XOR-Verknüpfung in Java:
int aa = 255 << 24;
int rr = r ^ R;
int gg = g ^ G;
int bb = b ^ B;
farbeBin3 = aa | rr | gg | bb;
Das dritte Quadrat erhält seine Farbe durch Anwendung von XOR auf alle Bits der ersten und zweiten Farbe.
Da wir keine Transparenz wünschen, reicht es, die ersten 24 Bit abzubilden. Ein Beispiel:
01100100 10001100 00110101 farbeBin1
00100001 01011100 11110000 farbeBin2
01000101 11010000 11000001 farbeBin1 XOR farbeBin2
00100001 01011100 11110000 farbeBin2
01100100 10001100 00110101 (farbeBin1 XOR farbeBin2) XOR farbeBin2
Wie Sie sehen, erhält man nach der wiederholten XOR-Verknüpfung mit farbeBin2 wieder den ursprünglichen Farbwert farbeBin1.
Die zweite Farbe kann man zur Verschlüsselung der ersten Farbe verwenden. Sie ist offensichtlich der Schlüssel
für beide Vorgänge: Zum Ver- und Entschlüsseln der Ursprungsfarbe.
Damit bekommt man ein Verfahren zur Ver- und Entschlüsselung eines Farbbildes, in dem man das beschriebene
Verfahren auf jedes Pixel anwendet. Die Bilddimensionen müssen dabei mit den Schlüsseldimensionen übereinstimmen.
Im Folgenden versuchen wir (der Einfachheit halber für ein Graustufenbild) einen Schlüssel zu
erzeugen, der hinreichend "zufällig" ist.
Den Sketch zur Erzeugung des Schlüssels können Sie sich
hier runterladen.
Alle notwendigen Erläuterungen findet man im Kapitel
Clifford Attraktors .
Die fünf zu wählenden Parameter können zum Beispiel so aussehen:
a = 0.9188442; b = 2.4275956; c = 2.1944933; d = -1.5525020; delta = 3.8372982;

Wir gehen davon aus, dass ein Graustufenbild der Dimension 1000x1000 verschlüsselt werden soll. Ändern Sie
gegebenenfalls
size() zum Bild passend.
Nachdem der Sketch gestartet wurde, findet man
bild2.bmp wie links (ohne Diagramm) im Programmordner.
Jedes Pixel hat einen Grauwert zwischen 0 und 255. Diese Werte sollten unbedingt gleichverteilt sein.
Das Programm ist bereits auf die Kontrolle vorbereitet. In der Console wird die Anzahl der Pixel mit Wert n ausgegeben.
Wir kopieren diese Daten in Exel oder in Libre Office Calc und lassen uns das zugehörige Balkendiagramm anzeigen.
Wie man links erkennen kann, ist die Gleichverteilung perfekt.
Kommen wir nun zum eigentlichen XOR-Verschlüsselungs Sketch
xorSW.
Wir benötigen, wie im Kapitel
Bildbearbeitung ,
zwei Methoden:
int[][] matrixVonBild(PImage bildEingabe)       PImage bildVonMatrix(int[][] matrix)
Legen Sie das zu verschlüsselnde Graustufenbild mit Namen bild1.jpg und das oben erstellte Schlüsselbild mit
Namen bild2.jpg in den Programmordner. Wie man eine Farbe mit XOR verschlüsselt, wissen Sie schon.
Bei einem Graustufenbild im RGB-Modus sind die Zahlenwerte für rot, grün und blau identisch. Das ändert am
Verfahren aber nichts. Noch immer müssen 32 Bit eingetragen werden.
bild1 = loadImage("bild1.bmp");
image(bild1,0,0);
bild2 = loadImage("bild2.bmp");
matrix1 = matrixVonBild(bild1);
matrix2 = matrixVonBild(bild2);
matrix3 = new int[w][h];
for(int i=0; i <h;i++){
    for(int j=0; j <w;j++){
        c1 = color(matrix1[i][j]);
        c2 = color(matrix2[i][j]);
        int a = 255 << 24;
        int r = int(red(c1)) <<16;
        int g = int(green(c1)) <<8;
        int b = int(blue(c1));
        int A = 255 <<24;
        int R = int(red(c2)) << 16;
        int G = int(green(c2)) <<8;
        int B = int(blue(c2));
        cBin1 = a | r | g | b;
        cBin2 = A | R | G | B;
        int aa = 255 << 24;
        int rr = r ^ R;
        int gg = g ^ G;
        int bb = b ^ B;
        cBin3 = aa | rr | gg | bb;
        matrix3[i][j] = cBin3;
   }
}
bild3 = bildVonMatrix(matrix3);
bild3.save("bild3.bmp");
Rechts oben das zu verschlüsselnde Bild, darunter das Ergebnis, abgespeichert unter bild3.bmp.
Um dieses Bild wieder zu entschlüsseln, speichern Sie bild3 als bild1 im Programmordner ab. Das
bedeutet, dass alle Pixelwerte ein zweites Mal mit XOR "verschlüsselt" werden. Und in der Tat finden wir
danach im Programmordner das ursprüngliche Bild als bild3.bmp.
Als letztes sollte die "Schlüsselempfindlichkeit" geprüft werden. Das ist schnell erledigt. In den
Processing eigenen Funktionen wird mit float gearbeitet. Selbst wenn wir die Parameter als double-Werte
anlegen, können wir uns nur auf sieben gültige Ziffern verlassen. Ändern Sie daher
bei der Schlüsselerzeugung eine einzelne Ziffer bei einem der fünf Parameter im Bereich dieser ersten sieben Ziffern.
Versuchen Sie nun das verschlüsselte Bild mit dem veränderten Schlüssel sichtbar zu machen.
Das Ergebnis ist Chaos. Somit ist auch diese Forderung erfüllt.
Es gibt also 10
35 verschiedene Schlüssel!
Es ist etwas umständlich mit zwei Tools zu arbeiten. Daher wird die Schlüsselerzeugung und die Ver/Ent-schlüsselung
in einen Sketch gepackt:
Sketch Schlüsselerzeugung und XOR-Verschlüsselung
Typisch Clifford-Attraktor: Mitunter bekommen Sie als Schlüssel kein Chaos-Bild, sondern eine
wie auch immer geartete Struktur:
Dann haben Sie zufällig eine der seltenen Parameter-Kombination gefunden, die wir im Kapitel
Clifford Attraktore mühsam
gesucht haben. Eigentlich müsste man schluesselXOR.bmp nicht speichern. Es reicht während der Rechnung
die Daten im Arbeitsspeicher zu haben. Damit man aber nicht versehentlich einen weniger chaotischen
Schlüssel verwendet, sollt man das Bild anschauen. Es gibt aber, wie Sie sehen werden, noch einen
zweiten Grund.
Wie sieht die Übergabe der Information konkret aus?
Nehmen wir an, Bob will Eve eine Nachricht zukommen lassen. Eve sollte den Schlüssel, bestehend aus fünf
Parametern haben. Dann erzeugt sie sich den schluesselXOR.bmp mit dem Sketch, den sie beispielsweise
hier
runterladen kann und entschlüsselt damit das Bild bzw. die Nachricht im Bild.
Wie aber kommt der Schlüssel zu Eve? Sicher wäre, Bob und Eve träfen sich mindestens ein Mal, um die fünf
Parameter festzulegen. Ein One-Time-Pad, das mit diesen Parametern erzeugt wird,
darf aber nur ein einziges Mal verwendet werden. Müssen sie sich daher vor jeder Sendung einer verschlüsselten
Nachricht treffen? Das wäre sinnlos! Dann könnten sie sich die Nachricht einfach sagen.
Nein, ein Treffen genügt, denn jede verschlüsselte Nachricht enthält fortan auch die
beim nächsten Mal zu verwendenten Parameter. Dieses Verfahren ist riskant, denn sollte es nur ein einziges
Mal gelingen, die Verschlüsselung zu knacken, dann kann man zukünftig bequem mitlesen.
Bisher gibt es ca. 10
40 verschiedene Schlüssel. Machen wir 10
80 daraus!
Permutation mit Clifford Attraktor
Die vier Bilder unten sind im Original jeweils 1200x1200 Pixel groß. Stellen Sie sich vor, Sie vertauschen
zufällig zwei Pixel, beginnend links oben und endend rechts unten. Ein Beispiel: Die Farbe des Pixel bei (345,129)
tauscht die Farben mit dem Pixel bei (24,954). Das wären in diesem Fall 1.44 Millionen Tauschvorgänge. Ein aktueller
Computer erledigt diese Aufgabe in 2 Sekunden. Kann man ein solches "Riesenpuzzle" mit Hilfe eines Computers wieder
in die ursprüngliche Form bringen?
Ja, kann man! Falls man die Tauschparameter gespeichert hat. Dann macht man, beginnend bei rechts unten und
endend links oben, alle Tauschaktionen wieder rückgängig. Dauert ebenfalls 2 Sekunden.
Und wie sieht es aus, wenn man diese Parameter nicht gespeichert hat? Versuchen wir, die Frage für ein sehr
kleines Bild, bestehend aus 16x16 Pixeln, zu beantworten. Nehmen wir weiter an, dass die Zahlenwerte von 1 bis
256 eingetragen sind. Die Zahlen stehen für die möglichen Grauwerte. Jeder Wert komme genau einmal vor.
Dann gibt es 256!, also etwa 10500 Möglichkeiten, die Zahlen bzw. Grauwerte zu verteilen. Noch Fragen?
Aber: Beim einem RGB-Farbbild gibt es mehr als 16 Millionen verschiedene Farbwerte. Wenn man nun ähnliche Werte kombiniert,
um damit versucht einen Bildteil zusammenzusetzen? Gute Idee, nur woher weiß ich, dass
das gefundene Bildsegment tatsächlich aus dem ursprünglichen Bild stammt? Was jedem sofort einleuchtet: Mit dem
Bild rechts neben der Provence-Landschaftsbild lassen sich unendlich viele sinnvolle Bilder zusammensetzten. Nicht überzeugt?
Dann verwenden wir ein Grau-Chaos-Bild als Quelle, um daraus durch Permutation ein anderes Grau-Chaos-Bild zu
erzeugen. Und genau das ist der Plan.
Zunächst erzeugen wir auf die gleiche Weise wie oben Clifford-Attraktor-Zufallszahlen. Allerdings doppelt so viele,
denn jeder Tausch benötigt zwei davon.
(Ist das Bild, wie bei uns, 1200x1200 Pixel groß, dann muss man in den
Einstellungen von Processing die Größe des zu verwendenden Arbeitsspeichers erhöhen -hier 8192 MB. Sollte
ihr Rechner zu wenig Speicher haben, muss die Bildgröße reduziert werden.)
Die Zufallszahlen wollen wir in
einer Textdatei speichern. Dazu muss man sie zunächst in einen String umformen. Wenn alle Zufallszahlen in
MatrixHisto[i][j] abgelegt sind, dann bekommt man zum Beispiel mit dieser Methode die
Umformung (Cols ist die doppelte Zahl der Spalten und rows die Anzahl der Zeilen des Bildes):
String[] stringVonMatrix(int[][] matrix){
    int[][] MatrixHisto = matrix;
    String[]schluessel = new String[n];
     for(int i = 0; i < Cols ; i++){
        for(int j = 0; j < rows; j++){
            String x = str(round(MatrixHisto[i][j])% cols);
            schluessel[i + j*Cols] = x;
        }
    }
   return schluessel;
}
Der Tauschvorgang beim Verschlüsseln lässt sich sehr einfach realisieren:
for(int i=0;i<cols;i++){
    for(int j=0;j<rows;j++){
        int nummer = 2*(i+j*cols);
        ax=Integer.parseInt(permSchluessel[nummer]);
        ay=Integer.parseInt(permSchluessel[nummer+1]);
        bx=i;by=j;
        tauschA = bildErgebnis.get(ax,ay);
        tauschB = bildErgebnis.get(bx,by);
        bildErgebnis.set(ax,ay,tauschB) ;
        bildErgebnis.set(bx,by,tauschA) ;
    }
}
Versuchen Sie mit Hilfe des obigen Codes den Tauschvorgang zum entschlüsseln zu schreiben.
Brauchen Sie Hilfe, dann laden Sie den
Sketch Schlüsselerzeugung und Permutation runter.
Bleibt die Frage: Ist der Schlüssel, wie im xor-Fall, empfindlich für kleine Änderungen in den Parametern?
Das lässt sich einfach überprüfen: Verschlüsseln sie ein Bild mit fünf Paramtern, die jeweils aus acht Ziffern bestehen.
Erzeugen Sie einen neuen Text-Schlüssel
schluessel[], wobei nur eine Ziffer eines Parameters geändert wurde.
Versuchen Sie nun damit das verschlüsselte Bild wieder zu entschlüsseln. Das Ergebnis ist Chaos!
Es gibt daher auch hier 10
40 verschiedene Schlüssel. Insgesamt also
10
40x10
40 = 10
80, sofern man für beide Vorgänge verschiedene Parameter wählt.
Wie sieht nun der gesamte Ver/Entschlüsselungsprozess aus?
Einmal müssen sich Bob und Eve treffen, um ihre ersten
10 Paramter festzulegen. Danach ist kein Kontakt mehr nötig. Nun möchte Bob eine geheime Nachricht an Eve schicken.
Bob verschlüsselt das Bild / den Text zuerst mit der ersten Methode (xor) und danach mit der zweiten (Permutation).
Auf dem Bild befinden sich auch die beim nächsten Mal zu verwendeten zehn Paramter. Eve entschlüsselt das
Bild zunächst mit der Permutationsmethode und danach mit xor. Sie notiert sich die neuen Parameter.
Vorausgesetzt, ihre Computer sind nicht kompromettiert, dann ist die Nachricht auch mit Quantencomputer
nicht zu entschlüsseln.
(Übrigens, die Anzahl der Atome im Universum liegt zwischen 10
84 und 10
89)
Es ist umständlich, mit zwei Programmen zu arbeiten. Versuchen Sie, die beiden Sketche in einem Sketch
zu realisieren. Es soll am Ende nur noch drei Aktionen geben: "Schlüssel erzeugen", "verschlüsseln" und "entschlüsseln",
so dass der Anwender von der doppelten Ver/Entschlüsselung nichts bemerkt.
Das Ergebnis können Sie
hier runterladen.
Noch immer ist die Anwendung nicht perfekt: Man benötigt den Processing-Editor und man muss die Parameter
in den Quelltext eingeben. Etwa in dieser Form:
Wie das funktioniert erfahren Sie
hier !
Sketch Farbe mit XOR verschlüsseln
Sketch Clifford Attraktor Schlüssel
Sketch SW-Bild verschlüsseln mit XOR
Sketch Schlüsselerzeugung und XOR-Verschlüsselung
Sketch Schlüsselerzeugung und Permutation
Sketch XOR und Permutation
Menu