Verschlüsselung verstehen

Was bringt Key-Wrapping?

Key-Wrapping, zu Deutsch auch „Schlüssel-Umhüllung“ oder „Schlüssel-Verpackung“, ist eine einfache Technik in der Kryptographie, die in fast allen gängigen Verschlüsselungsverfahren verwendet wird.

Verschlüsselte E-Mail ist ein perfektes Beispiel für die Anwendung von Key-Wrapping. Egal ob S/MIME mit X.509-Zertifikaten oder OpenPGP/GnuPG, eine verschlüsselte E-Mail wird immer unter Verwendung von hybrider Verschlüsselung erzeugt. Das bedeutet, dass nicht nur ein Verschlüsselungsalgorithmus verwendet wird, sondern zwei kombiniert werden. Als Anwender merken Sie davon nichts. Das alles geschieht im Hintergrund. Ein genauerer Blick auf die verschlüsselte E-Mail zeigt nur ihren RSA-Schlüssel oder ihr Zertifikat. Die E-Mail aber wurde zum Beispiel mit AES verschlüsselt.

Warum wird das gemacht? Die Antwort ist ganz einfach. Asymmetrische Verschlüsselung mit etwa RSA ist sehr langsam im Vergleich zu symmetrischen Algorithmen wie AES. Das Verfahren funktioniert wie folgt. Ein AES-Schlüssel (nennen wir ihn Session-Key) wird erzeugt und die E-Mail mit AES verschlüsselt. Der AES-Schlüssel wird dann mit RSA verschlüsselt und an die E-Mail angehängt. Ein AES-Schlüssel ist 16, 24 oder 32 Bytes groß und ist also im Vergleich zu einer E-Mail sehr klein.

Das gleiche Verfahren wird bei HTTPS (SSL/TLS) verwendet. Der Anwender sieht womöglich nur das RSA-Zertifikat des Servers, aber die eigentliche Verschlüsselung des Datenstroms geschieht symmetrisch. Dies gilt auch für SSH, SCP und andere Anwendungen.

Während in diesen Fällen der symmetrische Schlüssel unter Verwendung eines asymmetrischen Verschlüsselungsverfahrens "verpackt" wird, gibt es auch Anwendungen, die ein Key-Wrapping mit rein symmetrischen Verfahren verwenden. Dies gilt für viele Anwendungen, die eine Passwort-basierte Verschlüsselung umsetzen. Nehmen wir als Beispiel TrueCrypt - oder besser dessen als sicherer geltende Nachfolger. Haben Sie sich jemals gefragt, warum Sie ihr TrueCrypt-Passwort ändern können, aber ihre gesamte Festplatte nicht erneut verschlüsselt werden muss? Die Antwort ist: Aufgrund von Key-Wrapping.

Nehmen wir an, Sie verwenden TrueCrypt mit einem symmetrischen Verschlüsselungsverfahren. TrueCrypt erzeugt hierfür zum Beispiel einen AES-Schlüssel. Unter Verwendung von sicheren Ableitungsverfahren, wie PBKDF2 aus PKCS# 5, erzeugt TrueCrypt zusätzlich einen zweiten symmetrischen Schlüssel aus ihrem Passwort oder ihrer Passphrase. Dieser zweite Schlüssel wird dazu verwendet, den ersten Schlüssel zu verschlüsseln. Der erste Schlüssel wird auch als Hauptschlüssel oder Master-Key bezeichnet, weil er dazu verwendet wird, ihre Daten zu verschlüsseln. Der aus dem Passwort generierte Schlüssel wird dazu verwendet, um diesen Hauptschlüssel zu verschlüsseln (Wrapping). Wenn Sie ihr Passwort ändern, wird der Master-Key einfach neu verpackt, ändert sich aber nicht. Das neue Passwort führt lediglich zu einem neuen Schlüssel für das Key-Wrapping.

Die gleiche Technologie kann auch in anderen Anwendungen, zum Beispiel Web-Applikationen, verwendet werden. Das Anmelde-Passwort eines Nutzers kann hierbei für das Key-Wrapping benutzt werden. Die Java-Bibliothek CrococryptLib etwa bietet eine sehr einfache Möglichkeit, Passwort-basierte Verschlüsselung und Key-Wrapping in eine Vielzahl an Anwendungen zu integrieren. Durch die Verwendung von Key-Wrapping kann der Benutzer jederzeit sein Passwort ändern, ohne dass eine komplett erneute Verschlüsselung seiner Daten notwendig wird.

String passwort = "Passwort1";

Secret secret = new Secret(passwort);

//=== Verschlüsselung und Key-Wrapping ===

//Erzeugen eines AES-256 Master-Key

EncryptionKey encKey = EncryptionKey.generateNewKey();

//Erzeugen eines Passwort-basierten Schlüssels

CompactPasswordKey pwKey = CompactPasswordKey.generateKey(secret);

WrapUtil wrapper = new WrapUtil(pwKey);

byte[] pwKey_atStorage = pwKey.writeToBytes();

byte[] wrappedEncKey_atStorage = wrapper.wrapToBytes(encKey);

String message = "Eine einfache Textnachricht";

String encryptedMessage = new CompactEncryption(encKey).encryptToBase64(new StringData(message));

//=== Entschlüsselung ===

//Laden des Schlüsselmaterials

pwKey = CompactPasswordKey.newInstance(secret).readFromBytes(pwKey_atStorage);

wrapper = new WrapUtil(pwKey);

encKey = wrapper.unwrapFromBytes(wrappedEncKey_atStorage);

//Ausführen der Entschlüsselung

System.out.println("Entschlüsselte Nachricht: " +

new CompactEncryption(encKey).decryptFromBase64(encryptedMessage));

//=== Passwortwechsel und Erneuerung des Key-Wrappings

String neuesPasswort = "neuesPasswort";

CompactPasswordKey newPwKey = CompactPasswordKey.generateKey(new Secret(neuesPasswort));

//Hinweis: Der Master-Key bleibt unverändert.

wrappedEncKey_atStorage = wrapper.rewrapFromBytes(wrappedEncKey_atStorage, newPwKey);

pwKey_atStorage = newPwKey.writeToBytes();

//=== Erneute Entschlüsselung ===

//(nur zu Demonstrationszwecken)

encKey = new WrapUtil(newPwKey).unwrapFromBytes(wrappedEncKey_atStorage);

System.out.println("Entschlüsselte Nachricht: " +

new CompactEncryption(encKey).decryptFromBase64(encryptedMessage));

Dieses Beispiel kann als lauffähiges Eclipse-Projekt im CrococryptLib SDK(http://www.frankhissen.de/crococryptlib-documentation-frank-hissen-it-software.html) heruntergeladen und in eigenen Anwendungen frei verwendet werden. (mb)