Created
February 17, 2017 11:50
-
-
Save fernandocanizo/3e0c2be33592c94a9b237cb4d60e6c7d to your computer and use it in GitHub Desktop.
Façade class to handle password hashing on different versions of PHP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Creation Date: 2015.03.14 | |
// Author: Fernando L. Canizo - http://flc.muriandre.com/ | |
abstract class Password { | |
// Façade class to handle password hashing on different versions of PHP | |
// Uses password_hash() on PHP >= 5.5.0 | |
// Uses crypt() on PHP < 5.5.0 and >= 5.0.0 | |
public $phpVersion = null; | |
protected $function = 'password_hash'; | |
public static function init() { | |
self::$phpversion = phpversion(); | |
if(self::phpVersion < '5.0.0'): | |
// don't support PHP 4 | |
throw new Exception("We need PHP version >= 5.0.0 for password hashing function to work."); | |
elseif(self::phpVersion < '5.5.0'): | |
// password_hash() appeared in v5.5.0, switch to crypt() | |
self::$function = 'crypt'; | |
endif; | |
} | |
public static function getHash($password) { | |
$initializationVector = mcrypt_create_iv(22, MCRYPT_DEV_URANDOM); | |
if(false === $initializationVector): | |
throw new Exception("Couldn't create initialization vector for password hasshing."); | |
endif; | |
if(self::$function === 'crypt'): | |
// see http://php.net/security/crypt_blowfish.php about '$2y11$' | |
if(defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH): | |
$salt = '$2y$' . self::getCost() . '$' . $initializationVector; | |
return crypt($password, $salt); | |
else: | |
$salt = '$6$' . self::getCost() . '$' . $initializationVector; | |
return crypt($password, $salt); | |
endif; | |
else: // using password_hash | |
$option = array( | |
'cost' => self::getCost(), | |
'salt' => $initializationVector | |
); | |
if(false === ($passwordHash = password_hash($password, PASSWORD_DEFAULT, $options))): | |
throw new Exception("Couldn't create password hash."); | |
endif; | |
return $passwordHash; | |
endif; | |
} | |
/* | |
public static function verify($password) { | |
// checks a password string against saved password hash | |
} | |
*/ | |
protected static function getCost() { | |
// This code will benchmark your server to determine how high of a cost | |
// you can afford. You want to set the highest cost that you can | |
// without slowing down you server too much. 8-10 is a good baseline, | |
// and more is good if your servers are fast enough. The code below | |
// aims for ≤ 50 milliseconds stretching time, which is a good baseline | |
// for systems handling interactive logins. | |
$timeTarget = 0.05; // 50 milliseconds | |
if('crypt' === self::$function && defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH): | |
$cost = 10; | |
do { | |
$cost++; | |
$start = microtime(true); | |
password_hash('test', PASSWORD_BCRYPT, array('cost' => $cost)); | |
$end = microtime(true); | |
} while (($end - $start) < $timeTarget); | |
if($cost > 31) return 31; // cost should be between 04 and 31 | |
return $cost; | |
elseif('crypt' === self::$function): | |
$rounds = 5000; | |
return 'rounds=' . $rounds . '$'; | |
else: // password_hash | |
endif; | |
} | |
protected static function hashWithPasswordHash($password) { | |
// PASSWORD_DEFAULT: use the current best algorithm available | |
// Note: generated hash goes about 60 chars long, but use a DB column | |
// with enough space for future updates use varchar(255) | |
$options = array( | |
'cost' => self::getCost() | |
); | |
$hash = password_hash($password , PASSWORD_DEFAULT, $options); | |
if(false === $hash): | |
throw new Exception(__FILE__ . ':' . __LINE__ . ": Couldn't build a password hash."); | |
endif; | |
return $hash; | |
} | |
protected static function hashWithCrypt($password) { | |
} | |
protected static function hashWithSha512($password) { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment