oneside Geschrieben 28. März 2006 Teilen Geschrieben 28. März 2006 Hi, ich habe mir eine Klasse gebastelt, die einen String per mcrypt verschlüsselt und in einem Cookie ablegt. Ich spiel gerade ein wenig mit mcrypt rum, hänge aber irgendwie in der Luft, da die Klasse mal funktioniert und mal wieder nicht... Die Klasse vershlüsselt einen String und speicher diesen in einem Cookie über die Methode "set()". Über die Methode "Validate()" wird überprüft, ob der verschlüsselte String gleich einem übergebenen ist. Ich habe folgende Klasse "class.CookieAuth.php" geschrieben: class AuthCookie { // Handle für mcrypt private $td; // Verschlüsselungscode static $key = 'Testkey'; //mcrypt Informationen static $cypher = MCRYPT_BLOWFISH; static $mode = MCRYPT_MODE_CFB; //Informationen zum Cookie static $cookiename = 'AUTH'; public function __construct(){ $this->td = mcrypt_module_open(self::$cypher,'',self::$mode,''); } public function set($challengekey){ setcookie(self::$cookiename,$this->_encrypt($challengekey)); } public function validate($challengekey){ if (!($_COOKIE[self::$cookiename]) || $_COOKIE[self::$cookiename] == ""){ echo("Validate fehlgeschlagen, Cookiedaten nicht vorhanden!"); } if ($this->_decrypt($_COOKIE[self::$cookiename]) != $challengekey){ echo("Validate fehlgeschlagen, Cookiedaten stimmen nicht mit String überein!"); } } private function _encrypt($plaintext){ $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($this->td), MCRYPT_RAND); mcrypt_generic_init($this->td, self::$key,$iv); $crypttext = mcrypt_generic($this->td,$plaintext); mcrypt_generic_deinit($this->td); return $iv.$crypttext; } private function _decrypt($crypttext){ $ivsize = mcrypt_enc_get_iv_size($this->td); $iv = substr($crypttext,0,$ivsize); $crypttext = substr($crypttext,$ivsize); mcrypt_generic_init($this->td,self::$key,$iv); $plaintext = mdecrypt_generic($this->td,$crypttext); mcrypt_generic_deinit($this->td); return $plaintext; } function __destruct() { mcrypt_module_close($this->td); } } //Class [/PHP] Testweise habe ich eine Datei index.php' angelegt, um die Funktion der Klasse mal zu testen: [PHP] require_once("class.CookieAuth.php"); //Ein zu verschlüsselnder Teststring $challengekey = "XYZ"; //Neues Objekt anlegen $obj_cookie = new AuthCookie(); //Teststring verschlüsseln und in Cookie speichern $obj_cookie->set($challengekey); // Objekt löschen unset($obj_cookie); //++++++++++++++++++++++++++++++++++++++ // Testvalidierung //++++++++++++++++++++++++++++++++++++++ $obj_cookie = new AuthCookie(); //Entschlüsseln und vergleichen $obj_cookie->validate($challengekey); unset($obj_cookie); Öffne ich die 'index.php' jetzt im Browser, wird keine Meldung ausgegeben. Lade ich die Seite aber mehrmals hintereinander neu, klappt die Validierung in unregelmäßigen Abständen nicht. Dann bekomme ich "Validate fehlgeschlagen, Cookiedaten stimmen nicht mit String überein!" ausgegeben, was bedeutet, dass der in der 'index.php' übergebene '$challengekey' nicht mit dem entschlüsselten String übereinstimmt. Wo habe ich einen Fehler in der Klasse? Hab irgendwie gerade einen Hänger und verstehe nicht, wieso es manchmal klappt und manchmal dann eben nicht? Ich habe die Klasse schon X mal umgebaut, bekomme aber immer den gleichen Fehler :-( Gruß Oneside Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TimeOut Geschrieben 30. März 2006 Teilen Geschrieben 30. März 2006 So... Ich hab mich heute mal drangesetzt und das ein bisschen analysiert. Grundsätzlich habe ich keine großen Anmerkungen zu deiner Verschlüsselungsklasse, auch wenn ich persönlich einen komplett anderen Ansatz gewählt habe (hängt mit der Struktur meines Frameworks zusammen). Ich würde allerdings in validate() das zweite IF durch ein ELSEIF ersetzen. Weiterhin solltest du nicht auf !($_COOKIE[self::$cookiename]) prüfen, sondern auf !isset($_COOKIE[self::$cookiename]), ist einfach genauer. Theoretisch könntest du auch die oder-Bedingung mit in die !isset-Bedingung einfassen in dem du !empty() nutzt. Um auf dein Problem zurück zu kommen, es hat mich nen bisschen überlegen gekostet, woran es liegt. Ein paar mehr Echos in der validate-Funktion (Anzeige des Cookieinhalts) hat mich letztendlich darauf gebracht. Sobald der verschlüsselte String ein \" enthält, so scheint es Probleme mit der Übertragung vom/zum Browser zu geben. Das liegt daran, das der Output der Verschlüsselungsfunktionen nicht zwingend auch im anzeigbaren Zeichenbereich liegen müssen. In diesem Fall wäre eine base64-Encodierung aus praktischen Gründen angebracht. Schau dir am besten base64_encode() / base64_decode() an. Ansonsten mein (nicht ganz ins Klassenschema passender) Workaround: public function set($challengekey) { setcookie(self::$cookiename,base64_encode($this->_encrypt($challengekey))); } private function _decrypt($crypttext) { $crypttext = base64_decode($crypttext); ... Hoffe das hilft. In meinen anschliessenden Tests wurde der Cookie unter allen benutzten Browsern validiert, wenn er es sollte. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.