Improve passwords hashing

This commit is contained in:
Fedor A. Fetisov 2013-10-21 20:14:42 +04:00
parent c34ce4c17e
commit 4873d03d42
5 changed files with 64 additions and 14 deletions

View File

@ -264,7 +264,7 @@ function update_operator($operatorid, $login, $email, $password, $localename, $c
':code' => $code ':code' => $code
); );
if ($password) { if ($password) {
$values[':password'] = md5($password); $values[':password'] = calculate_password_hash($login, $password);
} }
$db->query( $db->query(
"update {chatoperator} set vclogin = :login, " . "update {chatoperator} set vclogin = :login, " .
@ -311,7 +311,7 @@ function create_operator($login, $email, $password, $localename, $commonname, $a
")", ")",
array( array(
':login' => $login, ':login' => $login,
':pass' => md5($password), ':pass' => calculate_password_hash($login, $password),
':localename' => $localename, ':localename' => $localename,
':commonname' => $commonname, ':commonname' => $commonname,
':avatar' => $avatar, ':avatar' => $avatar,
@ -489,9 +489,9 @@ function check_login($redirect = true) {
global $mibewroot, $session_prefix; global $mibewroot, $session_prefix;
if (!isset($_SESSION[$session_prefix."operator"])) { if (!isset($_SESSION[$session_prefix."operator"])) {
if (isset($_COOKIE['mibew_operator'])) { if (isset($_COOKIE['mibew_operator'])) {
list($login, $pwd) = preg_split("/,/", $_COOKIE['mibew_operator'], 2); list($login, $pwd) = preg_split('/\x0/', base64_decode($_COOKIE['mibew_operator']), 2);
$op = operator_by_login($login); $op = operator_by_login($login);
if ($op && isset($pwd) && isset($op['vcpassword']) && md5($op['vcpassword']) == $pwd && !operator_is_disabled($op)) { if ($op && isset($pwd) && isset($op['vcpassword']) && calculate_password_hash($op['vclogin'], $op['vcpassword']) == $pwd && !operator_is_disabled($op)) {
$_SESSION[$session_prefix."operator"] = $op; $_SESSION[$session_prefix."operator"] = $op;
return $op; return $op;
} }
@ -524,8 +524,7 @@ function check_login($redirect = true) {
function force_password($operator) function force_password($operator)
{ {
global $mibewroot; global $mibewroot;
if($operator['vcpassword']==md5('')) if (check_password_hash($operator['vclogin'], $operator['vcpassword'], '')) {
{
header("Location: $mibewroot/operator/operator.php?op=1"); header("Location: $mibewroot/operator/operator.php?op=1");
exit; exit;
} }
@ -558,7 +557,7 @@ function login_operator($operator, $remember) {
global $mibewroot, $session_prefix; global $mibewroot, $session_prefix;
$_SESSION[$session_prefix."operator"] = $operator; $_SESSION[$session_prefix."operator"] = $operator;
if ($remember) { if ($remember) {
$value = $operator['vclogin'] . "," . md5($operator['vcpassword']); $value = base64_encode($operator['vclogin'] . "\x0" . calculate_password_hash($operator['vclogin'], $operator['vcpassword']));
setcookie('mibew_operator', $value, time() + 60 * 60 * 24 * 1000, "$mibewroot/"); setcookie('mibew_operator', $value, time() + 60 * 60 * 24 * 1000, "$mibewroot/");
} else if (isset($_COOKIE['mibew_operator'])) { } else if (isset($_COOKIE['mibew_operator'])) {
@ -828,4 +827,55 @@ function get_operator_groupids($operatorid)
); );
} }
/**
* Calculate hashed password value based upon operator's login and password
*
* By default function tries to make us of Blowfish encryption algorithm,
* with salted MD5 as a second possible choice, and unsalted MD5 as a fallback
* option
*
* @param string $login operator's login
* @param string $password Operator's password (as plain text)
*
* @return string hashed password value
*/
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);
}
else {
$hash = crypt($password, '$2a$08$' . $login);
}
}
if ( (CRYPT_MD5 == 1) && !strcmp($hash, '*0') ) {
$hash = crypt($password, '$1$' . $login);
}
return strcmp($hash, '*0') ? $hash : md5($password);
}
/**
* Validate incoming hashed value to be the hashed value of operator's password
*
* @param string $login operator's login
* @param string $password Operator's password (as plain text)
* @param string $hash incoming hashed value
*
* @return boolean true if incoming value is the correct hashed value of
* operators' password and false otherwise
*/
function check_password_hash($login, $password, $hash)
{
if (preg_match('/^\$/', $hash)) {
return !strcmp(calculate_password_hash($login, $password), $hash);
}
else {
return !strcmp(md5($password), $hash);
}
}
?> ?>

View File

@ -27,7 +27,7 @@ $page = array(
'version' => $version, 'version' => $version,
'localeLinks' => get_locale_links("$mibewroot/operator/index.php"), 'localeLinks' => get_locale_links("$mibewroot/operator/index.php"),
'needUpdate' => Settings::get('dbversion') != $dbversion, 'needUpdate' => Settings::get('dbversion') != $dbversion,
'needChangePassword' => $operator['vcpassword'] == md5(''), 'needChangePassword' => check_password_hash($operator['vclogin'], '', $operator['vcpassword']),
'profilePage' => "$mibewroot/operator/operator.php?op=".$operator['operatorid'], 'profilePage' => "$mibewroot/operator/operator.php?op=".$operator['operatorid'],
'updateWizard' => "$mibewroot/install/", 'updateWizard' => "$mibewroot/install/",
'newFeatures' => Settings::get('featuresversion') != $featuresversion, 'newFeatures' => Settings::get('featuresversion') != $featuresversion,

View File

@ -27,7 +27,7 @@ if (isset($_POST['login']) && isset($_POST['password'])) {
$remember = isset($_POST['isRemember']) && $_POST['isRemember'] == "on"; $remember = isset($_POST['isRemember']) && $_POST['isRemember'] == "on";
$operator = operator_by_login($login); $operator = operator_by_login($login);
if ($operator && isset($operator['vcpassword']) && $operator['vcpassword'] == md5($password) && !operator_is_disabled($operator)) { if ($operator && isset($operator['vcpassword']) && check_password_hash($operator['vclogin'], $password, $operator['vcpassword']) && !operator_is_disabled($operator)) {
$target = $password == '' $target = $password == ''
? "$mibewroot/operator/operator.php?op=" . $operator['operatorid'] ? "$mibewroot/operator/operator.php?op=" . $operator['operatorid']

View File

@ -97,8 +97,8 @@ if ((isset($_POST['login']) || !is_capable(CAN_ADMINISTRATE, $operator)) && isse
update_operator($opId, $login, $email, $password, $localname, $commonname, $code); update_operator($opId, $login, $email, $password, $localname, $commonname, $code);
// update the session password // update the session password
if (!empty($password) && $opId == $operator['operatorid']) { if (!empty($password) && $opId == $operator['operatorid']) {
$toDashboard = $operator['vcpassword'] == md5('') && $password != ''; $toDashboard = check_password_hash($login, '', $operator['vcpassword']) && $password != '';
$_SESSION[$session_prefix."operator"]['vcpassword'] = md5($password); $_SESSION[$session_prefix."operator"]['vcpassword'] = calculate_password_hash($login, $password);
if($toDashboard) { if($toDashboard) {
header("Location: $mibewroot/operator/index.php"); header("Location: $mibewroot/operator/index.php");
exit; exit;
@ -125,7 +125,7 @@ if ((isset($_POST['login']) || !is_capable(CAN_ADMINISTRATE, $operator)) && isse
$page['opid'] = topage($opId); $page['opid'] = topage($opId);
} else { } else {
//show an error if the admin password hasn't been set yet. //show an error if the admin password hasn't been set yet.
if ($operator['vcpassword']==md5('') && !isset($_GET['stored'])) if (check_password_hash($operator['vclogin'], '', $operator['vcpassword']) && !isset($_GET['stored']))
{ {
$errors[] = getlocal("my_settings.error.no_password"); $errors[] = getlocal("my_settings.error.no_password");
} }
@ -149,7 +149,7 @@ $canmodify = ($opId == $operator['operatorid'] && is_capable(CAN_MODIFYPROFILE,
$page['stored'] = isset($_GET['stored']); $page['stored'] = isset($_GET['stored']);
$page['canmodify'] = $canmodify ? "1" : ""; $page['canmodify'] = $canmodify ? "1" : "";
$page['canchangelogin'] = is_capable(CAN_ADMINISTRATE, $operator); $page['canchangelogin'] = is_capable(CAN_ADMINISTRATE, $operator);
$page['needChangePassword'] = $operator['vcpassword'] == md5(''); $page['needChangePassword'] = check_password_hash($operator['vclogin'], '', $operator['vcpassword']);
prepare_menu($operator); prepare_menu($operator);
setup_operator_settings_tabs($opId, 0); setup_operator_settings_tabs($opId, 0);

View File

@ -52,7 +52,7 @@ if (count($errors) == 0 && isset($_POST['password'])) {
$db->query( $db->query(
"update {chatoperator} set vcpassword = ?, vcrestoretoken = '' " . "update {chatoperator} set vcpassword = ?, vcrestoretoken = '' " .
"where operatorid = ?", "where operatorid = ?",
array(md5($password), $opId) array(calculate_password_hash($operator['vclogin'], $password), $opId)
); );
$page['loginname'] = $operator['vclogin']; $page['loginname'] = $operator['vclogin'];