openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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:
test/PasswordTest.php | 22++++++++++++++++++++++
util/Password.class.php | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
util/include.inc.php | 1+
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')) )