-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix #1315 인증메일 및 비밀번호 찾기에서 새 비밀번호 및 인증키 발급 개선
- Loading branch information
bnu
committed
Mar 6, 2015
1 parent
867fb4a
commit 445a414
Showing
2 changed files
with
124 additions
and
41 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ | |
/** | ||
* This class can be used to hash passwords using various algorithms and check their validity. | ||
* It is fully compatible with previous defaults, while also supporting bcrypt and pbkdf2. | ||
* | ||
* | ||
* @file Password.class.php | ||
* @author Kijin Sung ([email protected]) | ||
* @package /classes/security | ||
|
@@ -40,7 +40,7 @@ public function getBestAlgorithm() | |
$algos = $this->getSupportedAlgorithms(); | ||
return key($algos); | ||
} | ||
|
||
/** | ||
* @brief Return the currently selected hashing algorithm | ||
* @return string | ||
|
@@ -62,7 +62,7 @@ public function getCurrentlySelectedAlgorithm() | |
} | ||
return $algorithm; | ||
} | ||
|
||
/** | ||
* @brief Return the currently configured work factor for bcrypt and other adjustable algorithms | ||
* @return int | ||
|
@@ -84,7 +84,7 @@ public function getWorkFactor() | |
} | ||
return $work_factor; | ||
} | ||
|
||
/** | ||
* @brief Create a hash using the specified algorithm | ||
* @param string $password The password | ||
|
@@ -101,28 +101,28 @@ public function createHash($password, $algorithm = null) | |
{ | ||
return false; | ||
} | ||
|
||
$password = trim($password); | ||
|
||
switch($algorithm) | ||
{ | ||
case 'md5': | ||
return md5($password); | ||
|
||
case 'pbkdf2': | ||
$iterations = pow(2, $this->getWorkFactor() + 5); | ||
$salt = $this->createSecureSalt(12); | ||
$hash = base64_encode($this->pbkdf2($password, $salt, 'sha256', $iterations, 24)); | ||
return 'sha256:'.sprintf('%07d', $iterations).':'.$salt.':'.$hash; | ||
|
||
case 'bcrypt': | ||
return $this->bcrypt($password); | ||
|
||
default: | ||
return false; | ||
} | ||
} | ||
|
||
/** | ||
* @brief Check if a password matches a hash | ||
* @param string $password The password | ||
|
@@ -136,36 +136,36 @@ public function checkPassword($password, $hash, $algorithm = null) | |
{ | ||
$algorithm = $this->checkAlgorithm($hash); | ||
} | ||
|
||
$password = trim($password); | ||
|
||
switch($algorithm) | ||
{ | ||
case 'md5': | ||
return md5($password) === $hash || md5(sha1(md5($password))) === $hash; | ||
|
||
case 'mysql_old_password': | ||
return (class_exists('Context') && substr(Context::getDBType(), 0, 5) === 'mysql') ? | ||
DB::getInstance()->isValidOldPassword($password, $hash) : false; | ||
|
||
case 'mysql_password': | ||
return $hash[0] === '*' && substr($hash, 1) === strtoupper(sha1(sha1($password, true))); | ||
|
||
case 'pbkdf2': | ||
$hash = explode(':', $hash); | ||
$hash[3] = base64_decode($hash[3]); | ||
$hash_to_compare = $this->pbkdf2($password, $hash[2], $hash[0], intval($hash[1], 10), strlen($hash[3])); | ||
return $this->strcmpConstantTime($hash_to_compare, $hash[3]); | ||
|
||
case 'bcrypt': | ||
$hash_to_compare = $this->bcrypt($password, $hash); | ||
return $this->strcmpConstantTime($hash_to_compare, $hash); | ||
|
||
default: | ||
return false; | ||
} | ||
} | ||
|
||
/** | ||
* @brief Check the algorithm used to create a hash | ||
* @param string $hash The hash | ||
|
@@ -198,7 +198,7 @@ function checkAlgorithm($hash) | |
return false; | ||
} | ||
} | ||
|
||
/** | ||
* @brief Check the work factor of a hash | ||
* @param string $hash The hash | ||
|
@@ -219,7 +219,7 @@ function checkWorkFactor($hash) | |
return false; | ||
} | ||
} | ||
|
||
/** | ||
* @brief Generate a cryptographically secure random string to use as a salt | ||
* @param int $length The number of bytes to return | ||
|
@@ -230,10 +230,10 @@ public function createSecureSalt($length, $format = 'hex') | |
{ | ||
// Find out how many bytes of entropy we really need | ||
$entropy_required_bytes = ceil(($format === 'hex') ? ($length / 2) : ($length * 3 / 4)); | ||
|
||
// Cap entropy to 256 bits from any one source, because anything more is meaningless | ||
$entropy_capped_bytes = min(32, $entropy_required_bytes); | ||
|
||
// Find and use the most secure way to generate a random string | ||
$is_windows = (defined('PHP_OS') && strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'); | ||
if(function_exists('openssl_random_pseudo_bytes') && (!$is_windows || version_compare(PHP_VERSION, '5.4', '>='))) | ||
|
@@ -262,14 +262,14 @@ public function createSecureSalt($length, $format = 'hex') | |
$entropy .= pack('S', rand(0, 65536) ^ mt_rand(0, 65535)); | ||
} | ||
} | ||
|
||
// Mixing (see RFC 4086 section 5) | ||
$output = ''; | ||
for($i = 0; $i < $entropy_required_bytes; $i += 32) | ||
{ | ||
$output .= hash('sha256', $entropy . $i . rand(), true); | ||
} | ||
|
||
// Encode and return the random string | ||
if($format === 'hex') | ||
{ | ||
|
@@ -282,7 +282,7 @@ public function createSecureSalt($length, $format = 'hex') | |
return strtr($salt, '+/=', $replacements); | ||
} | ||
} | ||
|
||
/** | ||
* @brief Generate the PBKDF2 hash of a string using a salt | ||
* @param string $password The password | ||
|
@@ -315,7 +315,7 @@ public function pbkdf2($password, $salt, $algorithm = 'sha256', $iterations = 81 | |
return substr($output, 0, $length); | ||
} | ||
} | ||
|
||
/** | ||
* @brief Generate the bcrypt hash of a string using a salt | ||
* @param string $password The password | ||
|
@@ -330,7 +330,7 @@ public function bcrypt($password, $salt = null) | |
} | ||
return crypt($password, $salt); | ||
} | ||
|
||
/** | ||
* @brief Compare two strings in constant time | ||
* @param string $a The first string | ||
|
@@ -347,6 +347,84 @@ function strcmpConstantTime($a, $b) | |
} | ||
return $diff === 0; | ||
} | ||
|
||
/** | ||
* @brief Generates a strong password | ||
* | ||
* @param int $length | ||
* @param bool $add_dashes | ||
* @param string $available_sets | ||
* @return string | ||
* | ||
* @link https://gist.github.com/tylerhall/521810 | ||
* | ||
* Generates a strong password of N length containing at least one lower case letter, | ||
* one uppercase letter, one digit, and one special character. The remaining characters | ||
* in the password are chosen at random from those four sets. | ||
* | ||
* The available characters in each set are user friendly - there are no ambiguous | ||
* characters such as i, l, 1, o, 0, etc. This, coupled with the $add_dashes option, | ||
* makes it much easier for users to manually type or speak their passwords. | ||
* | ||
* Note: the $add_dashes option will increase the length of the password by | ||
* floor(sqrt(N)) characters. | ||
*/ | ||
function generateStrongPassword($length = 10, $add_dashes = false, $available_sets = 'luds') | ||
{ | ||
$sets = array(); | ||
if(strpos($available_sets, 'l') !== false) | ||
{ | ||
$sets[] = 'abcdefghjkmnpqrstuvwxyz'; | ||
} | ||
|
||
if(strpos($available_sets, 'u') !== false) | ||
{ | ||
$sets[] = 'ABCDEFGHJKMNPQRSTUVWXYZ'; | ||
} | ||
|
||
if(strpos($available_sets, 'd') !== false) | ||
{ | ||
$sets[] = '23456789'; | ||
} | ||
|
||
if(strpos($available_sets, 's') !== false) | ||
{ | ||
$sets[] = '!@#$%&*?'; | ||
} | ||
|
||
$all = ''; | ||
$password = ''; | ||
foreach($sets as $set) | ||
{ | ||
$password .= $set[array_rand(str_split($set))]; | ||
$all .= $set; | ||
} | ||
|
||
$all = str_split($all); | ||
for($i = 0; $i < $length - count($sets); $i++) | ||
{ | ||
$password .= $all[array_rand($all)]; | ||
} | ||
|
||
$password = str_shuffle($password); | ||
|
||
if(!$add_dashes) | ||
{ | ||
return $password; | ||
} | ||
|
||
$dash_len = floor(sqrt($length)); | ||
$dash_str = ''; | ||
while(strlen($password) > $dash_len) | ||
{ | ||
$dash_str .= substr($password, 0, $dash_len) . '-'; | ||
$password = substr($password, $dash_len); | ||
} | ||
|
||
$dash_str .= $password; | ||
|
||
return $dash_str; | ||
} | ||
} | ||
/* End of file : Password.class.php */ | ||
/* Location: ./classes/security/Password.class.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