Systemvoraussetzung
- Linux
- Windows
- PHP 4 >= 4.3.0
- PHP 5
- libmcrypt 2.4.x oder 2.5.x
Datei(en)
aes_encrypt.php, aes_decrypt.php, aestext.txt
Problem
Die Verschlüsselung von Daten war, ist und wird immer ein Thema sein, mit
dem wir fast täglich konfrontiert werden. Jeder von uns besitzt Daten, die für
keinen anderen sichtbar sein sollten, aber in der Regel werden diese Daten
irgendwo im Klartext versteckt.
Natürlich ist das keine Lösung, da diese Daten gefunden werden können.
Gerade bei der Übermittlung der Daten im Internet besteht die Gefahr, dass
sie abgefangen und eingesehen werden. Wie aber schütze ich meine Daten am
besten?
Lösung
Wir müssen das Rad nicht neu erfinden, sondern ziehen bestehende Algorithmen
der Kryptografie heran. In unserem Beispiel werden wir auf Rijndael
zurückgreifen, der in einer abgeleiteten Fassung zum Advanced Encryption
Standard (AES) benannt wurde und im Oktober 2000 vom National Institute of
Standards and Technology (NIST) als Standard festgelegt wurde.
Bei Rijndael handelt es sich um einen symmetrischen Algorithmus mit einer
variablen Blockgröße von 128, 192 oder 256 Bit und einer variablen Schlüssellänge
von 128, 192 oder 256 Bit. In unserem Beispiel werden wir die höchste
Länge von 256 Bit nehmen, um einen maximalen Schutz zu gewährleisten.
Rijndael wurde von den beiden Belgiern Joan Daemen und Vincent Rijmen
entwickelt.
Eines möchten wir Ihnen nicht vorenthalten. Gerne werden AES und Rijndael
in einem Atemzug genannt, da ja AES eigentlich auch Rijndael ist. Es gibt
allerdings einen gravierenden Unterschied. AES nutzt für die Blockgrößen 128,
192 oder 256 Bit immer 16 Byte, Rijndael dagegen variable Werte:
128 Bit > 16 Byte
192 Bit > 24 Byte
256 Bit > 32 Byte
Somit können auch verschiedene Größen der IV-Tags
entstehen: bei AES grundsätzlich
16 Byte, bei Rijndael 16, 24 oder 32 Byte.
Die Sicherheit hängt von Ihrem Passwort ab. Je komplexer Ihr Passwort ist,
desto sicherer sind Ihre Daten verschlüsselt. Daher sollten Sie immer ein
Passwort wählen, das aus willkürlich gewählten Buchstaben, Zahlen und Sonderzeichen
besteht und über eine ausreichende Anzahl an Zeichen verfügt. Ein
komplexes und wirklich sicheres Passwort sieht folgendermaßen aus:
mNiDeUiBa27.03.1971IlG
Eine solche komplexe Zeichenfolge kann man sich natürlich nicht einfach
so merken. Eine Eselbrücke hilft Ihnen aber dabei, auch ein so komplexes
Passwort sicher im Gedächtnis zu behalten:
Mein Name ist Damir Enseleit und ich bin am 27.03.1971 in Lünen geboren.
Einen solchen Satz kann man sich sehr schnell merken. Um das Passwort
noch sicherer zu machen, habe ich abwechselnd für jedes Wort Klein- und
Großbuchstaben verwendet. Durch die Zahlen und Sonderzeichen wurde das
Passwort noch komplexer.
Es gibt wichtige und unwichtige Daten, also fragen Sie sich selbst, wann Sie ein
derart langes Passwort benötigen. Ein weniger komplexes Passwort aus nur
acht Zeichen ist in der Regel völlig ausreichend.
Da dieses Buch keine Ausarbeitung für Kryptografie ist und dieses Thema ein
ganzes Buch füllen würde, gehen wir nicht näher auf diese Zusammenhänge
ein, sondern konzentrieren uns wieder auf unser Beispiel.
Im Nachfolgenden sehen Sie den Text, den wir verschlüsseln werden, und die
Ausgabe, also den verschlüsselten Text.
Unverschlüsselter Text
Wir müssen das Rad nicht neu erfinden, sondern ziehen bestehende Algorithmen
der Kryptografie heran. In unserem Beispiel werden wir auf
den Advanced Encryption Standard (AES) zurückgreifen, der im Oktober
2000 vom National Institute of Standards and Technology (NIST) als Standard
festgelegt wurde. Bei AES handelt es sich um einen symmetrischen
Algorithmus mit einer variablen Blockgröße von 128, 192 oder 256 Bit und einer variablen Schlüssellänge von 128, 192 oder 256 Bit. In unserem
Beispiel werden wir auf die höchste Länge von 256 Bit zurückgreifen, um
einen maximalen Schutz zu gewährleisten. |
Verschlüsselter Text
_”@“8˜ Üñò÷<UVhùwxÞù=UTÌ“@0N$Š‘ôrš‚
ÊÇ£oe
‰êJÁ*EÉŽJ
ª[2DC?]. . . Å[8F?]Û1¨„» '±oe½DO\tÇMb½Z?:OE‡[8F?]
‹eÕÂ#}Ä×BúMó¯£z]
8Z,.:K#ÿOEä\ ȸè2É´!êºÚDÊj=pxÅð;÷S6|1@M¸Ÿq¤
[2C6?],€@(¯è [8D?]Õ1R®I’µ`ùZ±Çµ òï
¡æj[90?]g:ºP¡üZŸØ±Ä:c’öje»öVà™AX§¢ø‘/
ÃoN8ŸEµ[2DC?]›. . . ô. . . Q'Ùvÿ{}zDX® ±Nʼn[81?]qå
¾¥·P8F±C&|î
|\³zeúuf]]'j[2DC?]©[90?]OÓ‘X
ŠöÆèâŸTXŽJóLG{â¨ß?Û–øÁ![2DC?]u6[192?]$%aÙ˜¢˜üôB;é–
Ü1Ñ‚öïæGÿ§4µ9ë*[192?]Üm°CîNÃ [2DC?]§81äÿÓ¹ '}Uk.r¾ [9D?]T[90?]p±
êA×õPÜûˆÙ¡´ËÁ\oeJÆ[2C6?]ÓOF›ÝB ª€:&Ñ
—òÜçÐÈtoeÄaF§Ã‹ð¡‚ÿ[90?]Ú»OâOE²
.»d[¢«7Ô“ü¤ÝΤÝ?Ðùx»ÄÜ%‡'B†Jq§[2DC?]±¤KÒß² Éöx\
²„aKÊEàÓ[
81?]æùìÍI/¬ Üßz OEoî©Å³.{à[81?]Yw‚:v@æ%Pmõ:¤¯‘¬
’[9D?]g[8F?]e˜½ÏÛÝÄ|ô¸‘[81?]†!®&Ax†ù >°Ñ§¬5ÅxôÃ( c |
Grundvoraussetzung für die zuvor gesehene Verschlüsselung ist das Vorhandensein
gewisser Module. Überprüfen Sie Ihre phpinfo(), um zu sehen, ob
bei Ihnen libmcrypt 2.4.x oder 2.5.x installiert ist. Wenn ja, so sollten Sie
folgenden Eintrag sehen:
Abbildung 12.1: mcrypt
Windows-Benutzer
Falls Sie libmcrypt 2.4.x oder 2.5.x noch nicht auf Ihrem System haben sollten,
so finden Sie im beiliegendem ZIP-Archiv
die Datei libmcrypt.dll. Sie müssen diese Datei in den Ordner Ihres
System-Pfades
(z. B. c:\Windows\system32) kopieren. Anschließend öffnen Sie
die Datei php.ini und ändern folgende Zeile:
;extension=php_mcrypt.dll
in
extension=php_mcrypt.dll
Zum Schluss müssen Sie lediglich Ihren Webserver neu starten, und das Modul
sollte jetzt vorhanden sein. Dies können Sie ebenfalls mit einer phpinfo()
prüfen.
Unsere komplette Verschlüsselung besteht aus zwei Dateien – zum einen der
Datei für die Verschlüsselung (aes_encrypt.php) und zum anderen der Datei für
die Entschlüsselung (aes_decrypt.php). Der Einfachheit halber haben wir diese
Dateien in unserem Beispiel getrennt. Sie können aber beide Funktionen in den
Dateien zusammenlegen und jeweils die geforderte Funktion ansprechen.
function encryptAES($file,$key,$aes)
@param string $file
@param string $key
@param string $aes
@return bool
Die Funktion encryptAES() verlangt insgesamt drei Parameter. Zum einen
den Dateinamen ($file) (38) der Datei, die verschlüsselt werden soll. Des
Weiteren das Passwort ($key) (38) für die Verschlüsselung und zum Schluss
die Verschlüsselungsstärke ($aes) (38).
Wie bereits erwähnt, sollten Sie ein sicheres Passwort für die Verschlüsselung
auswählen – in unserem Beispiel ist es ein leichtes Passwort, dient aber dem
Zweck. Bei der Verschlüsselungsstärke können Sie aus einer variablen Schlüssellänge
von 128, 192 oder 256 Bit auswählen. Hier im Beispiel haben wir die
stärkste Verschlüsselung verwendet, also 256 Bit.
Zuerst überprüfen wir, ob die angegebene zu verschlüsselnde Datei (41) vorhanden
ist. Sollte dies der Fall sein, speichern (42) wir den kompletten Inhalt
der Datei in die Variable $content. Fehlt die Datei, so brechen wir die Funktion
ab (44) und geben FALSE zurück.
Im nächsten Schritt erfragen wir, welche Schlüssellänge genutzt werden
soll (47-56)
und setzen den jeweiligen Parameter, den wir in die Variable $rijndael speichern. Diesen Parameter benötigen wir, um das passende
Modul für die Verschlüsselung zu laden (in unserem Fall hier rijndael-256).
Wir laden im nächsten Schritt unser Modul und übergeben als zusätzlichen
Parameter den Modus OFB (Output Feedback Modus). Dieser Modus bestimmt,
wie die Daten verschlüsselt werden sollen. Dabei handelt es sich um die Art
der Blockchiffrierung, wir gehen aber hier aufgrund des Umfangs nicht weiter
auf dieses Thema ein. Mögliche Werte sind:
CBC Cipher Block Chaining Modus
CFB Cipher Feedback Modus
ECB Electronic Codebook Modus
OFB Output Feedback Modus
Wenn Sie beim Verschlüsseln von Daten z. B. den Modus OFB angegeben haben,
so müssen Sie unbedingt auch beim Entschlüsseln diesen Modus wählen, da
die Daten sonst abweichen würden!
Wir müssen abfragen, ob es sich bei dem Betriebssystem um einen Windows- oder
Linuxrechner (67) handelt, da Windows nur den Parameter MCRYPT_RAND
(68) für die Erstellung des Initialisierungsvektors kennt.
Seit PHP 4.2.0 ist es nicht mehr notwendig, den Zufallsgenerator mit srand()
zu initialisieren und wir verzichten somit darauf, da dieses Beispiel eine
Mindestkonfiguration von PHP 4 >= 4.3.0, PHP 5 hat. Sie können dieses Beispiel
ohne weiteres auf eine Mindestkonfiguration von PHP 4 >= 4.1.1 umprogrammieren
– dafür müssen Sie lediglich in der Datei aes_decrypt.php,
file_get_contents() in eine fopen()Variante
ändern.
Nachdem wir das Betriebssystem ermittelt haben, setzen wir den Initialisierungs-Vektor
(68 oder 70), der für das Verschlüsseln verwendet wird – diesen Vektor
benötigen wir, wenn CBC, CFB oder OFB als Blockchiffrierung gewählt wurde.
Auch hier gilt das gleiche Prinzip wie bei der Wahl der Blockchiffrierung –
der gleiche Initialisierungs-Vektor
muss beim Ver- und
Entschlüsseln genutzt
werden.
Wir ermitteln im nächsten Schritt die maximale Schlüsselgröße (74) für unsere
256-Bit-Verschlüsselung
– die Schlüsselgröße bei 256 Bit beträgt 32 Byte. Mit
diesem Wert und unserem Passwort können wir jetzt den eigentlichen Schlüssel
erstellen (77), der aus einem MD5-Code
(liefert uns einen 32 Byte langen String)
gebildet und mit substr() (77) eventuell auf unsere maximale Schlüsselgröße
(hier von 32 Bytes) gekürzt wird.
Vor jeder Ver- oder
Entschlüsselung müssen alle Buffers, also der Speicher, der
zur temporären Zwischenlagerung der Daten für die Ver- oder
Entschlüsselung
dient, initialisiert werden (80). Im Umkehrschluss müssen wir nach der Ver- oder
Entschlüsselung diesen Speicher wieder freigeben (99). Nachdem wir alle
Vorbereitungen getroffen haben, können wir unsere Daten verschlüsseln (83).
Wir speichern jetzt zum einen unseren verschlüsselten Text in eine Datei (89-91)
(mit der Dateiendung *.aes) und zum anderen unseren IV-Tag
(94-96), der als Dateiendung *.iv erhalten wird. Wie bereits im Vorfeld erwähnt, benötigen
Sie für die Entschlüsselung beides, den verschlüsselten Text sowie den IV-Tag.
Wir können jetzt den Speicher wieder freigeben (99) und das Modul schließen
(102). Fertig ist unsere Verschlüsselung, und wir können uns jetzt dem
Entschlüsseln widmen.
038:
039: 040: 041: 042: 043: 044: 045: 046: 047: 048: 049: 050: 051: 052: 053: 054: 055: 056: 057: 058: 059: 060: 061: 062: 063: 064: 065: 066: 067: 068: 069: 070: 071: 072: 073: 074: 075: 076: 077: 078: 079: 080: 081: 082: 083: 084: 085: 086: 087: 088: 089: 090: 091: 092: 093: 094: 095: 096: 097: 098: 099: 100: 101: 102: 103: 104: 105: 106: 107: 108:
|
function encryptAES($file,$key,$aes)
{
// Überprüft, ob die Datei vorhanden ist und liest sie ein if(file_exists($file)) $content = file_get_contents($file); else return false; // Setzt den Algorithmus
switch ($aes) {
case 128: $rijndael = 'rijndael-128'; break; case 192: $rijndael = 'rijndael-192'; break; default: $rijndael = 'rijndael-256'; }
// Setzt den Verschlüsselungsalgorithmus // und setzt den Output Feedback (OFB) Modus $cp = mcrypt_module_open($rijndael, '', 'ofb', ''); // Ermittelt den Initialisierungsvector, der für die Modi CBC, CFB
// und OFB benötigt wird.
// Der Initialisierungsvector muss beim Entschlüsseln den selben
// Wert wie beim Verschlüsseln haben.
// Windows unterstützt nur MCRYPT_RAND
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($cp), MCRYPT_RAND); else $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($cp), MCRYPT_DEV_RANDOM); // Ermittelt die Anzahl der Bits, welche die Schlüssellänge
// des Keys festlegen
$ks = mcrypt_enc_get_key_size($cp); // Erstellt den Schlüssel, der für die Verschlüsselung genutzt wird $key = substr(md5($key), 0, $ks); // Initialisiert die Verschlüsselung mcrypt_generic_init($cp, $key, $iv);
// Verschlüsselt die Daten $encrypted = mcrypt_generic($cp, $content); // Extrahiert den Dateinamen $fileName = basename($file); // Speichert die verschlüsselten Daten $fp = fopen($fileName.".aes","w"); fputs($fp,$encrypted); fclose($fp); // Speichert den IV-Tag $fp = fopen($fileName.".iv","w"); fputs($fp,$iv); fclose($fp); // Deinitialisiert die Verschlüsselung mcrypt_generic_deinit($cp); // Schließt das Modul mcrypt_module_close($cp); return true; }
encryptAES("aestext.txt","MeinPasswort",192); |
Beispiel 12.12: aes_encrypt.php
Die Verschlüsselung haben wir nun einwandfrei gelöst und ausreichend beschrieben.
Daher wird die Entschlüsselung ein wenig kürzer, und wir erklären
nicht alles bisher Gesehene nochmals so ausführlich. Sollten Sie Begriffe nicht
auf Anhieb verstehen, so lesen Sie im vorherigen Beispiel mit der ausführlichen
Erklärung noch einmal nach.
function decryptAES($file,$key,$aes,$ivFile)
@param string $file
@param string $key
@param string $aes
@param string $ivFile
@return mixed
Die Funktion decryptAES() verlangt als Parameter die verschlüsselte Datei
($file *.aes), das Passwort im Klartext ($key – nicht den Schlüssel), die
Verschlüsselungsart ($iv – 128, 192 oder 256) und zum Schluss die Datei mit
dem IV-Tag
($ivFile – *.iv).
Zuerst überprüfen wir, ob beide Dateien (*.aes und *.iv) vorhanden sind (39)
und speichern bei Erfolg den verschlüsselten Inhalt (43) und den IV-Tag
(44)
jeweils in eine Variable. Ist eine Datei nicht vorhanden, so brechen wir die Funktion
ab und geben FALSE zurück (46). Die switch-Abfrage
(49-58)
benötigen
wir wieder, um das passende Modul für die Entschlüsselung zu wählen.
Wieder öffnen wir das Modul (62) (in unserem Fall rijndael-256),
setzen den Modus
auf OFB (62) und ermitteln die maximale Schlüsselgröße (65). Im nächsten
Schritt erstellen wir anhand unseres Passworts den Schlüssel (68) mit der maximalen
Schlüssellänge und initialisieren alle Buffers für die Entschlüsselung
(71).
Die zuvor eingelesene Datei werden wir jetzt entschlüsseln (74). Vielleicht
ist Ihnen bereits aufgefallen, dass wir hier keinen IV-Tag
gebildet haben. Wie
bereits erwähnt, benötigen wir jetzt den IV-Tag
aus der Datei *.iv, der bei der
Verschlüsselung erstellt wurde.
Mit diesem speichern wir jetzt den entschlüsselten Text in unsere Variable
$decrypted, deinitialisieren unsere Buffer (77) und schließen das Modul (80).
Zum Schluss entfernen wir noch die eventuellen Null-Bytes
(82) in unserem
entschlüsselten Text und geben den Text an die aufrufende Stelle zurück.
Das war's! Dieser Abschnitt war nun zwar kurz, trotzdem denke ich, das das
vorherige Beispiel erklärend genug war und Sie jetzt in der Lage sind, die
Mechanismen bei der Verschlüsselung zu verstehen.
39:
40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88:
|
function decryptAES($file,$key,$aes,$ivFile)
{
// Überprüft, ob die Datei vorhanden ist und liest sie ein if(file_exists($file) && file_exists($ivFile)) {
$content = file_get_contents($file); $iv = file_get_contents($ivFile);
} else
return false; // Setzt den Algorithmus
switch ($aes) {
case 128: $rijndael = 'rijndael-128'; break; case 192: $rijndael = 'rijndael-192'; break; default: $rijndael = 'rijndael-256'; }
// Setzt den Verschlüsselungsalgorithmus // und setzt den Output Feedback (OFB) Modus $cp = mcrypt_module_open($rijndael, '', 'ofb', ''); // Ermittelt die Anzahl der Bits, welche die Schlüssellänge des Keys festlegen $ks = mcrypt_enc_get_key_size($cp); // Erstellt den Schlüssel, der für die Verschlüsselung genutzt wird $key = substr(md5($key), 0, $ks); // Initialisiert die Verschlüsselung mcrypt_generic_init($cp, $key, $iv);
// Entschlüsselt die Daten $decrypted = mdecrypt_generic($cp, $content); // Beendet die Verschlüsselung mcrypt_generic_deinit($cp); // Schließt das Modul mcrypt_module_close($cp); return trim($decrypted); }
$decrypted = decryptAES("aestext.txt.aes","MeinPasswort",256,"aestext.txt.iv");
echo $decrypted;
|
Beispiel 12.13: aes_decrypt.php
Dieses Beispiel diente der Vorführung der Verschlüsselung. Das Programm an
sich ist noch sehr unvollständig und könnte erweitert werden. Daher werden
wir im nächsten Beispiel eine Anwendung auf Basis von MySQL programmieren,
damit Sie auch komfortabel testen können.
Dieses Skript aus dem SELFPHP KOCHBUCH wurde von SELFPHP unter dem "Tarif Mc500" von McAc.net-Webhosting erfolgreich ausgeführt und getestet!
Auf der Übersichtseite unter "McAc.net – Webhosting zu diesem Buch" finden Sie weitere Informationen zu dem Webhostingpaket, dass durch SELFPHP getestet wurde.
|