Teil von  SELFPHP
  +++ SELFPHP CronJob-Service :: Jetzt auch als Professional-Version verfügbar! +++



:: Anbieterverzeichnis ::

Globale Branchen

Informieren Sie sich über ausgewählte Unternehmen im Anbieterverzeichnis von SELFPHP  

 

:: SELFPHP Forum ::

Fragen rund um die Themen PHP? In über 120.000 Beiträgen finden Sie sicher die passende Antwort!  

 

:: Newsletter ::

Abonnieren Sie hier den kostenlosen SELFPHP Newsletter!

Vorname: 
Name:
E-Mail:
 
 

:: Qozido ::

Die Bilderverwaltung mit Logbuch für Taucher und Schnorchler.   

 
 
Symmetrische Textverschlüsselung mit Rijndael (AES)


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_OS03)) === '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.


 




:: Premium-Partner ::

Webhosting/Serverlösungen


Premium-Partner MECO Systemhaus GmbH & Co. KG
Premium-Partner PSW GROUP GmbH & Co. KG
Premium-Partner BPI-Systeme
Premium-Partner Pixel X
Premium-Partner
 

:: SELFPHP Sponsoren ::


Microsoft Deutschland GmbH
twosteps.net - ...Premium-Webhosting
Sedo - Bei uns wird PHP großgeschrieben
hostfactory.ch - OptimaNet Schweiz AG
ZEND - The PHP Company
Kaspersky Labs
HighText iBusiness
SELFPHP Sponsoren
 

Qozido


© 2001-2009 E-Mail SELFPHP OHG, info@selfphp.deImpressumKontakt