HINWEIS: Die Informationen auf dieser Seite sind für die Arbeit mit WinZip® nicht von Bedeutung, sondern lediglich für die Entwickler von Dienstprogrammen zur Verarbeitung von ZIP-Dateien gedacht.
Dieses Dokument enthält Informationen für Entwickler und andere interessierte Benutzer, die die AES-Verschlüsselungsformate AE-1 und AE-2 in eigenen ZIP-Dateidienstprogrammen unterstützen möchten. WinZip Computing übernimmt keinerlei Garantie für die in diesem Dokument enthaltenen Informationen. Insbesondere bietet WinZip Computing keine Gewähr für die Fehlerfreiheit dieser Informationen oder ihre Eignung für einen bestimmten Zweck sowie dafür, dass das hier beschriebene Dateiformat auch in künftigen WinZip-Versionen unterstützt wird. Es wird ausdrücklich empfohlen, jeglichen Code und alle Verfahren mit der üblichen Sorgfalt zu testen und zu validieren.
Diese Informationen dienen als Ergänzung zu den im Dokument Informationen zur AES-Verschlüsselung: Verschlüsselungsspezifikation AE-1 und AE-2 behandelten Grundlagen.
In diesem Dokument wird davon ausgegangen, dass Sie das AES-Encryption-Paket von Dr. Brian Gladman verwenden. Dr. Gladman hat in großzügiger Weise eine Beispielanwendung veröffentlicht, die die Verwendung seiner Encryption/Decryption- und anderer Routinen demonstriert. Die im Folgenden dargestellten Codebeispiele wurden dieser Beispielanwendung entnommen. Die AES-Bibliothek und die Beispielanwendung können von der AES-Projektseite auf Dr. Gladmans Website heruntergeladen werden.
Generieren von Saltwerten
Bitte lesen Sie die Informationen zu Saltwerten in der Verschlüsselungsspezifikation.
Dr. Gladman hat in den Dateien PRNG.C und PRNG.H einen Pseudozufallszahlengenerator bereitgestellt, der für das Generieren von Saltwerten verwendet werden kann. Diese Dateien sind in dem Beispielpaket enthalten, das auf der AES-Projektseite auf Dr. Gladmans Website zum Download bereitsteht.
Im Folgenden finden Sie einige Richtlinien für den Einsatz von Dr. Gladmans Generator. Bitte beachten Sie, dass der Generator ähnlich wie ein E/A-Stream verwendet, also geöffnet (initialisiert), eingesetzt und anschließend wieder geschlossen wird. Es wird empfohlen, den Generator beim Starten der Anwendung zu initialisieren und zusammen mit der Anwendung zu schließen. (Wenn Sie Ihren Code in C++ schreiben, sollten Sie diese Aktionen in eine C++-Klasse packen, die den Generator beim Aufbau initialisiert und beim Abbau wieder schließt.)
int entropy_fun( unsigned char buf[], unsigned int len) { unsigned __int64 pentium_tsc[1]; unsigned int i; static unsigned int num = 0; // this sample code returns the following sequence of entropy information // - the current 8-byte Windows performance counter value // - an 8-byte representation of the current date/time // - an 8-byte value built from the current process ID and thread ID // - all subsequent calls return the then-current 8-byte performance // counter value switch (num) { case 1: ++num; // use a value that is unlikely to repeat across system reboots GetSystemTimeAsFileTime((FILETIME *)pentium_tsc); break; case 2: ++num; { // use a value that distinguishes between different instances of this // code that might be running on different processors at the same time unsigned __int32 processtest = GetCurrentProcessId(); unsigned __int32 threadtest = GetCurrentThreadId(); pentium_tsc[0] = processtest; pentium_tsc[0] = (pentium_tsc[0] << 32) + threadtest; } break; case 0: ++num; // fall through to default case default: // use a rapidly-changing value // Note: check QueryPerformanceFrequency() first to // ensure that QueryPerformanceCounter() will work. QueryPerformanceCounter((LARGE_INTEGER *)pentium_tsc); break; } for(i = 0; i < 8 && i < len; ++i) buf[i] = ((unsigned char*)pentium_tsc)[i]; return i; }Hinweis: Der für die Entropiefunktion benötigte Prototyp ist in PRNG.H definiert.
prng_ctx ctx; prng_init(entropy_fun, &ctx);Diese Funktion muss während einer Anwendungssitzung nur einmal aufgerufen werden (sofern der Stream zwischenzeitlich nicht geschlossen wird).
unsigned char buffer[16]; prng_rand(buffer, sizeof(buffer), &ctx);
Beachten Sie, dass es sich bei dem Parameter ctx um dieselbe Variable prng_ctx handelt, die auch beim Initialisierungsaufruf verwendet wurde.
prng_end(&ctx);
Hierbei handelt es sich bei dem Parameter ctx wiederum um dieselbe Variable prng_ctx, die auch beim Initialisierungsaufruf verwendet wurde.
Verschlüsselung und Entschlüsselung
Das Ver- und Entschlüsseln der Daten funktioniert auf ganz ähnliche Weise, wiederum mithilfe eines Streams: der Stream wird "geöffnet", erhält die zu verschlüsselnden oder zu entschlüsselnden Daten und wird anschließend wieder geschlossen. Beim öffnen des Streams wird der Kennwortprüfwert und beim Schließen des Streams der Authentifizierungscode zurückgegeben.
Führen Sie die folgenden grundlegenden Schritte aus:
Die Initialisierung erfolgt beim Verschlüsseln und beim Entschlüsseln auf dieselbe Art und Weise:
fcrypt_ctx zctx; // the encryption context int rc = fcrypt_init( KeySize, // extra data value indicating key size pszPassword, // the password strlen(pszPassword), // number of bytes in password achSALT, // the salt achPswdVerifier, // on return contains password verifier &zctx); // Verschlüsselungskontext
Der Rückgabewert 0 gibt an, dass der Stream erfolgreich initialisiert wurde. Alle anderen Rückgabewerte deuten auf Fehler hin. Beachten Sie, dass es sich bei Kennwörtern um durch Nullen begrenzte ANSI-Zeichenfolgen handelt, die keine Nullen enthalten dürfen. (Um Kompatibilitätsprobleme zwischen den verschiedenen gängigen Zeichensätzen, insbesondere in unterschiedlichen Windows-Versionen, zu vermeiden, sollten die Benutzer dazu angehalten werden, Kennwörter zu verwenden, die ausschließlich aus den Standardzeichen 32 bis 127 bestehen.)
Die Funktion gibt mit achPswdVerifier den Kennwortprüfwert zurück (hierfür ist ein 2-Byte-Puffer erforderlich). Beim Verschlüsseln speichern Sie diesen Wert wie in der Verschlüsselungsspezifikation angegeben in der ZIP-Datei, beim Entschlüsseln vergleichen Sie den Rückgabewert mit dem in der ZIP-Datei gespeicherten Wert. Wenn die beiden Werte voneinander abweichen, hat entweder der Benutzer ein falsches Kennwort eingegeben, oder die Datei wurde nach dem Verschlüsseln in irgendeiner Weise verändert. (Beachten Sie, dass bei der Eingabe eines falschen Kennworts immer noch eine Wahrscheinlichkeit von 1 zu 65.536 besteht, dass die beiden Werte übereinstimmen.)
Der initialisierte Verschlüsselungskontext (zctx) wird als Parameter für die Encryption/Decryption-Funktionen verwendet. Aus diesem Grund muss sein Zustand bis zum Schließen des Streams beibehalten werden.
Verschlüsseln:
fcrypt_encrypt( pchData, // pointer to the data to encrypt cb, // how many bytes to encrypt &zctx); // Verschlüsselungskontext
Entschlüsseln:
fcrypt_decrypt( pchData, // pointer to the data to decrypt cb, // how many bytes to decrypt &zctx); // Entschlüsselungskontext
Unter Umständen müssen Sie die Verschlüsselungs- oder Entschlüsselungsfunktion mehrmals aufrufen und hierbei den jeweils nächsten Datenchunk an den Puffer übergeben. Um die Kompatibilität mit der AE-1- und der AE-2-Spezifikation zu gewährleisten, muss die Puffergröße ein Vielfaches von 16 Byte betragen, wobei lediglich der letzte Puffer naturgemäß kleiner sein kann. Aus Gründen der Effizienz sollte im Allgemeinen ein deutlich größerer Puffer von beispielsweise 32.768 Byte verwendet werden.
Hinweis: Beim Verschlüsseln von Nulllängedateien können Sie diesen Schritt einfach überspringen. Der Kennwortprüfwert (Schritt 1) und der Authentifizierungscode (Schritt 3) werden jedoch auch hierbei ermittelt und verwendet.
Schließen Sie den Stream nach dem Verschlüsseln bzw. Entschlüsseln wie folgt:
int rc = fcrypt_end( achMAC, // on return contains the authentication code &zctx); // Verschlüsselungskontext
Der Rückgabewert entspricht der Größe des Authentifizierungscodes und lautet bei AE-1 und AE-2 stets 10. Der Authentifizierungscode selbst wird mit achMAC an Ihren Puffer übergeben. Hierbei handelt es sich um ein für die Aufnahme von mindestens 10 Zeichen dimensioniertes char-Array. Beim Verschlüsseln speichern Sie diesen Wert wie in der Verschlüsselungsspezifikation angegeben in der ZIP-Datei, beim Entschlüsseln vergleichen Sie den Rückgabewert mit dem in der ZIP-Datei gespeicherten Wert. Wenn die beiden Werte voneinander abweichen, hat entweder der Benutzer ein falsches Kennwort eingegeben, oder die verschlüsselten Daten wurden nach dem Speichern in irgendeiner Weise verändert.
Beachten Sie, dass die Entschlüsselung auch dann fehlschlagen kann, wenn die verschlüsselten Daten nicht verändert wurden und der in Schritt 1 ermittelte Kennwortprüfwert korrekt war. Der Kennwortprüfwert eignet sich nur zu einer raschen überprüfung im Vorfeld und erkennt die meisten falschen Kennwörter. Da hierbei jedoch noch keine Prüfung des Kennworts selbst erfolgt, besteht immer noch eine Chance von 1 zu 65,536, dass ein falsches Kennwort nicht erkannt wird. Aus diesem Grund sollten Sie auch bei korrektem Kennwortprüfwert nach Abschluss des Vorgangs den Authentifizierungscode prüfen.
Hinweise
Änderungsverlauf
Änderungen gegenüber Dokumentversion 1.04 vom Juli 2008:
Die Beispiel-Entropiefunktion wurde um Informationen am Beginn des Entropie-Streams erweitert, die den Tag sowie den jeweiligen Prozess und Thread angeben.
Dokumentversion: 1.04
Zuletzt geändert: 21. Juli 2008
Copyright© 2003-2008 Corel Corporation.
Alle Rechte vorbehalten