From 524302fb2ef94680acda24f65a255d68ece46a50 Mon Sep 17 00:00:00 2001 From: "Fedor A. Fetisov" Date: Fri, 11 Jul 2014 09:20:49 +0000 Subject: [PATCH] Prevent use of an invalid salt for Blowfish hashing of passwords --- src/mibew/libs/operator.php | 59 +++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/src/mibew/libs/operator.php b/src/mibew/libs/operator.php index 7cb2906a..7e049e9e 100644 --- a/src/mibew/libs/operator.php +++ b/src/mibew/libs/operator.php @@ -837,9 +837,9 @@ function calculate_password_hash($login, $password) $hash = '*0'; if (CRYPT_BLOWFISH == 1) { if (defined('PHP_VERSION_ID') && (PHP_VERSION_ID > 50306)) { - $hash = crypt($password, '$2y$08$' . $login); + $hash = crypt($password, '$2y$08$' . generate_bf_salt($login)); } else { - $hash = crypt($password, '$2a$08$' . $login); + $hash = crypt($password, '$2a$08$' . generate_bf_salt($login)); } } @@ -850,6 +850,61 @@ function calculate_password_hash($login, $password) return strcmp($hash, '*0') ? $hash : md5($password); } +/** + * Generates correct blowfish salt based a string. + * + * @param string $string A string which should be turned to blowfish salt. + * @return string Correct blowfish salt. + */ +function generate_bf_salt($string) +{ + $result = ''; + $bin = unpack('C*', md5($string, true)); + for ($i = 0; $i < count($bin); $i++) { + $shift = 2 + ($i % 3) * 2; + $first = ($bin[$i + 1] >> $shift); + $second = ($bin[$i + 1] & bindec(str_repeat('1', $shift))); + switch ($shift) { + case 2: + $result .= bf_salt_character($first); + $tmp = $second; + break; + case 4: + $result .= bf_salt_character(($tmp << 4) | $first); + $tmp = $second; + break; + case 6: + $result .= bf_salt_character(($tmp << 2) | $first); + $result .= bf_salt_character($second); + break; + } + } + if ($shift == 2) { + $result .= bf_salt_character($second); + } + + return $result; +} + +/** + * Convert character code to a correct blowfish character. + * + * @param integer $num Character code. + * @return string Character that can be used in blowfish salt. + */ +function bf_salt_character($num) +{ + if ($num > 63) { + return chr(46); + } elseif ($num < 12) { + return chr(46 + $num); + } elseif ($num < 38) { + return chr(53 + $num); + } else { + return chr(59 + $num); + } +} + /** * Validate incoming hashed value to be the hashed value of operator's password *