commit 79fb57219518f7d1700d69440f07862dca7435b9
parent a2297e0a1325cb3aa924f059f68838f0a74efe4f
Author: Jan Dankert <devnull@localhost>
Date: Tue, 26 Feb 2013 23:24:14 +0100
Hashfunktionen für Passwörter in neuer Klasse "Password" mit Unterstützung für Bcrypt.
Diffstat:
3 files changed, 99 insertions(+), 0 deletions(-)
diff --git a/test/PasswordTest.php b/test/PasswordTest.php
@@ -0,0 +1,21 @@
+<?php
+
+include('../util/Password.class.php');
+?>
+
+<p>
+<?php
+echo "Hash: ".Password::hash("wtf");
+?>
+</p>
+
+
+<p>
+<?php
+echo "Check: ".Password::check("wtf",'$2y$10$LNY2qCb9elkMe/ITN09cB.6t5QqDzm9Uh9h/LV1I');
+
+echo "Check: ".Password::check("wtf",'aadce520e20c2899f4ced228a79a3083');
+
+
+?>
+</p>+
\ No newline at end of file
diff --git a/util/Password.class.php b/util/Password.class.php
@@ -0,0 +1,75 @@
+<?php
+
+
+/**
+ * Hashfunktion für Passwörter.
+ *
+ * Als Hashfunktion wird Bcrypt verwendet. Falls Bcrypt nicht zur
+ * Verfügung steht, erfolgt ein Fallback auf MD5.
+ *
+ * @author dankert
+ *
+ */
+class Password
+{
+ /**
+ * Hashen eines Kennwortes mit Bcrypt (bzw. MD5).
+ * @param $password
+ * @param $cost Kostenfaktor: Eine Ganzzahl von 4 bis 31.
+ */
+ static public function hash( $password,$cost=10 )
+ {
+ if ( function_exists('crypt') && defined('CRYPT_BLOWFISH') && CRYPT_BLOWFISH == 1 )
+ {
+ $chars = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+ $salt = '';
+ for( $i = 1; $i <= 22; $i++ )
+ $salt .= $chars[ rand(0,63) ];
+
+ //
+ if ( version_compare(PHP_VERSION, '5.3.7') >= 0 )
+ $algo = '2y';
+ else
+ $algo = '2a';
+
+ // Kostenfaktor muss zwischen '04' und '31' (jeweils einschließlich) liegen.
+ $cost = max(min($cost,31),4);
+ $cost = str_pad($cost, 2, '0', STR_PAD_LEFT);
+
+ return crypt($password,'$'.$algo.'$'.$cost.'$'.$salt.'$');
+ }
+ else
+ {
+ return md5($password);
+ }
+ }
+
+ /**
+ * Prüft das Kennwort gegen einen gespeicherten Hashwert.
+ *
+ * @param String $password Passwort
+ * @param String $hash Hash
+ * @return boolean true, falls das Passwort dem Hashwert entspricht.
+ */
+ static public function check( $password,$hash )
+ {
+ if ( substr($hash,0,1) != '$' )
+ // Wenn kein '$' voransteht, dann handelt es sich wohl um
+ // einen alten MD5-Hash
+ return $hash == md5($password);
+
+ elseif ( function_exists('crypt') )
+ {
+ // Workaround: Die Spalte 'password' ist z.Zt. nur 50 Stellen lang, daher
+ // wird der mit crypt() erzeugte Hash auf die Länge des gespeicherten Hashes
+ // gekürzt. Falls die Spalte später länger ist, wirkt automatisch die volle
+ // Hash-Länge.
+ return $hash == substr(crypt($password,$hash),0,strlen($hash));
+ }
+ else
+ {
+ throw new Exception("Modular crypt format is not supported by this PHP version (no function 'crypt()')");
+ }
+ }
+}
+?>+
\ No newline at end of file
diff --git a/util/include.inc.php b/util/include.inc.php
@@ -10,6 +10,7 @@ require_once( OR_SERVICECLASSES_DIR."TemplateEngine.class.".PHP_EXT );
require_once( OR_SERVICECLASSES_DIR."Preferences.class.".PHP_EXT );
require_once( OR_SERVICECLASSES_DIR."FileUtils.class.".PHP_EXT );
require_once( OR_SERVICECLASSES_DIR."JSON.class.".PHP_EXT );
+require_once( OR_SERVICECLASSES_DIR."Password.class.".PHP_EXT );
//if ( !empty($REQ[REQ_PARAM_ACTION]) && in_array($REQ[REQ_PARAM_ACTION],array('tree')) )