Windige Festplattenverschlüsselung

Seite 5: Windige Festplattenverschlüsselung

Inhaltsverzeichnis

Mit dieser Tabelle kann man ein kleines C-Programm schreiben, das den vermuteten Verschlüsselungsalgorithmus implementiert:

/* gcrypt.c by Harald Bögeholz / c't */

#include <stdio.h>

typedef long long LWORD;

LWORD crypt_bits[64] =
{
0x0000000000000100LL, /* 0000000000000001 */
0x0000000000002000LL, /* 0000000000000002 */
0x0000000000000002LL, /* 0000000000000004 */
...
0x0100000000000000LL /* 8000000000000000 */
};

int main(void)
{
LWORD word, eword;
int i;

while (1 == fread(&word, sizeof word, 1, stdin))
{
eword = 0;
for (i=0; i<64; ++i)
if (word & (1LL << i))
eword ^= crypt_bits[i];
fwrite(&eword, sizeof eword, 1, stdout);
}

return 0;
}

Es prüft für jedes auf stdin eingelesene 64-Bit-Wort der Reihe nach jedes Bit und fügt bei gesetzten Bits das zugehörige Muster aus der Tabelle dem Ergebniswort eword per Exklusiv-Oder hinzu.

Spannender und für die Praxis nützlicher ist natürlich die Decodierung. Sie funktioniert genau nach demselben Schema, nur benötigt man eine andere Tabelle decrypt_bits[]. Während die Tabelle crypt_bits[] zu jedem Klartextbit das zugehörige Bitmuster im Chiffrat enthält, ist es bei decrypt_bits umgekehrt: Für jedes Bit des Chiffrats steht dort ein Bitmuster im Klartext. (Für Mathematiker: Es geht hier einfach darum, die 64×64-Matrix über {0, 1} zu invertieren.)

Zum Glück hat die Tabelle ja einen ziemlich einfachen Aufbau: In den meisten Bitmustern des Chiffrats ist nur genau ein Bit gesetzt. Das Umkrempeln der Tabelle beschränkt sich also im Wesentlichen darauf, die Zeilen aufsteigend nach den Bits des Chiffrats zu ordnen. Nur in den oben mit * markierten Zeilen ist Nacharbeit gefragt, weil hier im Chiffrat mehrere Bits gesetzt sind. Man könnte das Invertieren der Matrix programmieren, aber da es nur so wenige Zeilen zum Puzzlen gab, habe ich es von Hand im Emacs gemacht. Das Ergebnis sieht so aus:

LWORD decrypt_bits[64] =
{
0x0000000000007c7dLL, /* 0000000000000001 (war 000000000000937f) */
0x0000000000000004LL, /* 0000000000000002 */
0x0000000000002000LL, /* 0000000000000004 */
0x0000000000000020LL, /* 0000000000000008 */
0x0000000000000010LL, /* 0000000000000010 */
0x0000000000000800LL, /* 0000000000000020 */
0x0000000000000040LL, /* 0000000000000040 */
0x0000000000000100LL, /* 0000000000000080 */
0x0000000000000001LL, /* 0000000000000100 */
0x0000000000000400LL, /* 0000000000000200 */
0x0000000000000080LL, /* 0000000000000400 */
0x0000000000008000LL, /* 0000000000000800 */
0x0000000000004000LL, /* 0000000000001000 */
0x0000000000000002LL, /* 0000000000002000 */
0x0000000000000200LL, /* 0000000000004000 */
0x0000000000001000LL, /* 0000000000008000 */
0x00000000b70c0000LL, /* 0000000000010000 (war 00000000ca870000) */
0x0000000000040000LL, /* 0000000000020000 */
0x0000000020000000LL, /* 0000000000040000 */
0x0000000000200000LL, /* 0000000000080000 */
0x0000000000100000LL, /* 0000000000100000 */
0x0000000008000000LL, /* 0000000000200000 */
0x0000000000400000LL, /* 0000000000400000 */
0x0000000001000000LL, /* 0000000000800000 */
0x0000000000010000LL, /* 0000000001000000 */
0x0000000004000000LL, /* 0000000002000000 */
0x0000000000800000LL, /* 0000000004000000 */
0x0000000080000000LL, /* 0000000008000000 */
0x0000000040000000LL, /* 0000000010000000 */
0x0000000000020000LL, /* 0000000020000000 */
0x0000000002000000LL, /* 0000000040000000 */
0x0000000010000000LL, /* 0000000080000000 */
0x0000007800000000LL, /* 0000000100000000 (war 0000005900000000) */
0x0000000400000000LL, /* 0000000200000000 */
0x0000200000000000LL, /* 0000000400000000 */
0x0000002000000000LL, /* 0000000800000000 */
0x0000001000000000LL, /* 0000001000000000 */
0x0000080000000000LL, /* 0000002000000000 */
0x0000004000000000LL, /* 0000004000000000 */
0x0000010000000000LL, /* 0000008000000000 */
0x0000000100000000LL, /* 0000010000000000 */
0x0000040000000000LL, /* 0000020000000000 */
0x0000008000000000LL, /* 0000040000000000 */
0x0000800000000000LL, /* 0000080000000000 */
0x0000400000000000LL, /* 0000100000000000 */
0x0000000200000000LL, /* 0000200000000000 */
0x0000020000000000LL, /* 0000400000000000 */
0x0000100000000000LL, /* 0000800000000000 */
0x78e2000000000000LL, /* 0001000000000000 (war 7057000000000000) */
0x0800000000000000LL, /* 0002000000000000 */
0x1000000000000000LL, /* 0004000000000000 */
0x0400000000000000LL, /* 0008000000000000 */
0x2000000000000000LL, /* 0010000000000000 */
0x0200000000000000LL, /* 0020000000000000 */
0x4000000000000000LL, /* 0040000000000000 */
0x0100000000000000LL, /* 0080000000000000 */
0x8000000000000000LL, /* 0100000000000000 */
0x0008000000000000LL, /* 0200000000000000 */
0x0010000000000000LL, /* 0400000000000000 */
0x0004000000000000LL, /* 0800000000000000 */
0x0020000000000000LL, /* 1000000000000000 */
0x0002000000000000LL, /* 2000000000000000 */
0x0040000000000000LL, /* 4000000000000000 */
0x0001000000000000LL /* 8000000000000000 */
};

Mit dieser Tabelle unter einem von CD gebooteten Knoppix übersetzt, hat das Programm das verschlüsselte Datenlaufwerk auf der GStor Plus korrekt decodiert – Verschlüsselung geknackt.

Das wäre natürlich nicht so einfach gewesen, hätte man nicht die Möglichkeit gehabt, speziell gewählte Klartextwörter durch die Platte chiffrieren zu lassen (Chosen Plain Text Attack). Aber auch durch reine Analyse des Chiffrats dürfte sich die Verschlüsselung einem Experten nicht lange widersetzen, zumal man ja über die auf einer Platte üblicherweise gespeicherten Datenstrukturen einige Annahmen treffen kann (Known Plaintext Attack).

Laut Excelstor arbeitet jedes Laufwerk mit einem anderen Schlüssel, sodass das hier vorgestellte Decodierprogramm für ein anderes Exemplar der GStor Plus nicht funktioniert. Schaut man in die obigen Tabellen, so ist aber nicht schwer zu erraten, wo dieser Schlüssel wohl sitzt: In genau vier Zeilen der Verschlüsselungstabelle, nämlich bei Bit 3, 19, 35 und 51 hat man offenbar ein 16-Bit-Wort als Schlüssel eingebaut, wobei das niederwertige Bit dieses Worts eine Eins sein muss, damit die Matrix invertierbar bleibt. Somit dürfte es sich um nur 60 Schlüsselbits handeln, von denen sich die ersten 15 zum Beispiel durch die bekannte Signatur 55 AA am Ende des MBR rekonstruieren lassen dürften.

Das Ganze hat übrigens einschließlich Programmierung gerade mal zwei Stunden gedauert, wobei eine halbe Stunde allein dafür draufging, von Hand im Emacs eine Matrix zu invertieren. Die Verschlüsselung der GStor Plus ist also allenfalls als milde Datenverschleierung zu bezeichnen. Als Schutz für vertrauliche Daten taugt sie definitiv nicht. Nach dieser Erkenntnis dachte ich mir: Mal schauen, ob sich der Passwortschutz ebenso leicht aushebeln lässt. Mehr dazu im nächsten Teil dieses Artikels. (bo)