Henryk Plötz: Verschlüsseln synchron

Beitrag lesen

Moin,

Und weil bunte Bilder allgemein beliebt sind hier noch ein Nachtrag. Zuerst aber noch eine Anmerkung:

Schlüssel: #%')(&$"!

hab ich etwas vorschnell aus meinem Tool kopiert. Das ist der Schlüssel wie er intern in meinem Tool vorlag. Die Version die hotte benutzt hat dürfte wohl eher [3, 5, 7, 9, 8, 6, 4, 2, 1] sein, also Zahlen zwischen 1 und 9 (mein Tool hat ASCII-Zeichen benutzt, und 32 draufaddiert).

Die anfängliche Vorgehensweise ist wie damals:
Zuerst der übliche Blick auf den ciphertext als Hexdump nach BASE64-Dekodierung:

zeigt wieder viel und sich wiederholendes ASCII -> schwache Verschlüsselung. Autokorrelation um die Schlüssellänge zu gewinnen deutet eine Schlüssellänge von 20 an:

Da damit aber die Entschlüsselung nicht auf Anhieb klappt ist wohl doch ein genauerer Blick vonnöten. Also mein Lieblingstool anwerfen, den Dotplot (hier für 10gramme):

Das verrät schon mal viel über die Struktur der Originaldatei: Sie besteht aus zwei deutlich voneinander verschiedenen Teilen, die Grenze liegt ungefähr bei Offset 7400. Der erste Teil ist recht wild, aber der zweite Teil besteht selbst wieder aus drei leicht unterschiedlichen Teilen. Die nah beieinanderliegenden Streifen im Dotplot des zweiten Teils haben übrigens einen Abstand von 80, die weit entfernten Streifen einen Abstand von 1800. Sollte die die Schlüssellänge etwa 180 sein? Das trau' ich hotte ehrlich gesagt nicht zu.

Noch eine Nebenbemerkung zur Struktur: hier mal die ASCII-Werte der einzelnen Zeichen im Ciphertext über ihrem Offset aufgetragen:

Man erkennt in den drei Unterteilungen des zweiten Teils der Datei eine wiederkehrende aufsteigende Sequenz (sieht man noch besser wenn man reinzoomt, aber ich will das Posting nicht mit unnötig vielen Bildern verpesten).

Zurück zur Schlüssellänge: Bei dem angenommenen einfachen Algorithmus müssten die Histogramme für alle Zeichen die mit dem gleichen Schlüsselbyte verschlüsselt wurden ungefähr gleich sein, aber verschoben. Gehen wir für den Augenblick erstmal von Schlüssellänge 20 aus und tragen die Histogramme für die Zeichen auf die mit dem ersten Schlüsselbyte verschlüsselt wurden:

  
c = load("ciphertext.txt");  
hold on  
for i = 1:3; hist(c(i:20:13438),1:130); endfor  

Das sieht nicht richtig aus. Während man im Bereich über 100 zwar mit etwas Phantasie noch sagen könne dass das blaue und rote Histogramm ungefähr gleich dem grünen, aber verschoben ist, sind sie in den Bereichen darunter --besonders zu sehen im Bereich von 33 bis 42-- ungefähr identisch.

Tatsächlich sieht jedes der Teilhistogramme ungefähr genauso wie das Histogramm über die gesamte Datei aus:

In erster Näherung sieht das eigentlich sogar fast wie das zu erwartende Histogramm einer unverschlüsselten Datei aus, mit leicht verbreiterten Balken. Die Häufung bei 10 aufwärts sind Zeilenumbrüche, bei 32 aufwärts Leerzeichen, dann ein Hügel für Zahlen, ein kleiner Hügel für Großbuchstaben und ein großer Hügel für Kleinbuchstaben. Die Breite des Leerzeichenspikes verrät uns den Werteumfang des Schlüssels: Es handelt sich offenbar um Verschiebungen zwischen 1 und 9 (inklusive). Das ist um eine Größenordnung weniger als bei dem 'normalen' naiven Ansatz mit einem ASCII-Text als Schlüssel. Ausserdem wurden die Verschiebungen offenbar auch nicht als ASCII-String eingegeben (sonst wäre die kleinste Verschiebung mindestens 10 (Zeilenumbruch), eher 32 (Leerzeichen)) sondern als Liste von Zahlen.

Anyway, Schlüssellänge. Durch Zufall hab ich mir den Geheimtext mal nicht als Hexdump sondern als normalen ASCII-Text angesehen:

Hier fällt das ^M^N in der ersten Zeile auf, was man vorher im Hexdump nicht so deutlich gesehen hat. Davor und dahinter steht jeweils auch ungefähr der gleiche Text. Gehen wir mal als Arbeitshypothese von einer Windows-Textdatei mit CRLF als Zeilentrenner aus, dann müssten das Zeilenumbrüche sein die mit den gleichen Schlüsselbytes verschlüsselt wurden. Ihr Abstand ist 9, also ist das jetzt unsere Schlüssellänge. Und tatsächlich, wenn man wieder die Histogramme für die einzelnen Schlüsselbytes eines 9 Byte langen Schlüssels malt, kommt was raus was richtig aussieht:

Jedes der einzelnen Histogramme einen klar definierten und 1 Zeichen Breiten Spike für das Leerzeichen, so muss das aussehen. Den Schlüssel könnte man jetzt hier an dem Histogramm ablesen, aber ich hatte dafür ein paar Zeilen Python geschrieben die das machen und dann den Klartext ausgeben. Hier also das Histogramm für den Klartext:

Man sieht den Leerzeichenspike und zwei Spikes bei 9 und 10. Stellt sich raus das das keine Windows-Datei ist, sondern die im Klartext nah beieinanderliegenden Zeichen unter 32 je ein Tab (0x9) und ein Zeilenumbruch (0xa) sind. Und zur allgemeinen Belustigung noch ein Dotplot (wieder 10gramme) für den Klartext:

Ein Blick auf den Klartext zeigt auch, warum die Autokorrelation die Schlüssellänge nicht gezeigt hat: Die Datei ist in sich so extrem stark strukturiert, und die 'Verschlüsselung' unterdrückt die Struktur so wenig (wie man an den Dotplots sieht) dass die Regularität im hinteren Teil der Datei durchgedrückt hat. Dort finden sich sehr viele, fast identische Zeilen (die sich nur in der aufsteigenden Nummer unterscheiden, daher die aufsteigende Struktur die man oben im Plot der ASCII-Werte gesehen) die jeweils 20 Bytes lang sind. Das kleinste gemeinsame Vielfache von 9 und 20 ist 180 (konnte man im Dotplot ja schön sehen), das war der andere Kandidat für die Schlüssellänge. Oh, und natürlich funktioniert mein Schlüsselfinderskript auch wenn man ihm sagt der Schlüssel wäre 180 Byte lang.

--
Henryk Plötz
Grüße aus Berlin
~~ Help Microsoft fight software piracy: Give Linux to a friend today! ~~