password_verify php не совпадает

Я пытаюсь проверить пароль с помощью функции password_verify с опубликованным паролем пользователя и хешем из базы данных.

Во-первых, как я генерирую пароль и хэш:

$user_password = $this->generate_password();

private function generate_password($length = 8)
{
 $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_-=+;:,.?";
 $password = substr( str_shuffle( $chars ), 0, $length );
 return $password;
}

define("HASH_COST_FACTOR", "10");
$hash_cost_factor = (defined('HASH_COST_FACTOR') ? HASH_COST_FACTOR : null);
$user_password_hash = password_hash($user_password, PASSWORD_DEFAULT, array('cost' => $hash_cost_factor));


$sql = "INSERT INTO users (user_name, user_password_hash, user_email, user_creation_timestamp)
VALUES (:user_name, :user_password_hash, :user_email, :user_creation_timestamp)";
$query = $this->db->prepare($sql);
$query->execute(array(':user_name' => $user_name,
                      ':user_password_hash' => $user_password_hash,
                      ':user_email' => $user_email,
                      ':user_creation_timestamp' => $user_creation_timestamp));
$count =  $query->rowCount();
if ($count != 1) {
   $_SESSION["feedback_negative"][] = FEEDBACK_ACCOUNT_CREATION_FAILED;
 return false;
}

  if ($this->sendUserpassword($user_email, $user_password)) {
      $_SESSION["feedback_positive"][] = FEEDBACK_ACCOUNT_SUCCESSFULLY_CREATED;
      return true;
  } else {
      $query = $this->db->prepare("DELETE FROM users WHERE user_id = :last_inserted_id");
      $query->execute(array(':last_inserted_id' => $user_id));
      $_SESSION["feedback_negative"][] = FEEDBACK_PASSWORD_MAIL_SENDING_FAILED;
      return false;
  }
private function sendUserpassword($user_email, $user_password)
{
  $mail = new PHPMailer;

  if (EMAIL_USE_SMTP) {
      $mail->IsSMTP();
      $mail->SMTPDebug = PHPMAILER_DEBUG_MODE;
      $mail->SMTPAuth = EMAIL_SMTP_AUTH;
      if (defined(EMAIL_SMTP_ENCRYPTION)) {
          $mail->SMTPSecure = EMAIL_SMTP_ENCRYPTION;
      }
      $mail->Host = EMAIL_SMTP_HOST;
      $mail->Username = EMAIL_SMTP_USERNAME;
      $mail->Password = EMAIL_SMTP_PASSWORD;
      $mail->Port = EMAIL_SMTP_PORT;
      } else {
        $mail->IsMail();
      }

  $mail->From = EMAIL_PASSWORD_FROM_EMAIL;
  $mail->FromName = EMAIL_PASSWORD_FROM_NAME;
  $mail->AddAddress($user_email);
  $mail->Subject = EMAIL_PASSWORD_SUBJECT;
  $mail->Body = EMAIL_PASSWORD_CONTENT . '/' . $user_password;

  if($mail->Send()) {
    $_SESSION["feedback_positive"][] = FEEDBACK_PASSWORD_MAIL_SENDING_SUCCESSFUL;
    return true;
  } else {
    $_SESSION["feedback_negative"][] = FEEDBACK_PASSWORD_MAIL_SENDING_ERROR . $mail->ErrorInfo;
    return false;
  }
}

Подтвердить при входе в систему:

if (!isset($_POST['user_name']) OR empty($_POST['user_name'])) {
  $_SESSION["feedback_negative"][] = FEEDBACK_USERNAME_FIELD_EMPTY;
  return false;
}

if (!isset($_POST['user_password']) OR empty($_POST['user_password'])) {
  $_SESSION["feedback_negative"][] = FEEDBACK_PASSWORD_FIELD_EMPTY;
  return false;
}

$sth = $this->db->prepare("SELECT user_id,
                           user_name,
                           user_email,
                           user_password_hash,
                           user_active,
                           user_account_type
                           FROM   users
                           WHERE  (user_name = :user_name OR user_email = :user_name)");

$sth->execute(array(':user_name' => $_POST['user_name'], ':provider_type' => 'DEFAULT'));
$count =  $sth->rowCount();

if ($count != 1) {
  $_SESSION["feedback_negative"][] = FEEDBACK_LOGIN_FAILED;
  return false;
}    

$result = $sth->fetch();

//check via password_verify
if (password_verify($_POST['user_password'], $result->user_password_hash)) {
  ...
  return true;
} else {
  $_SESSION["feedback_negative"][] = FEEDBACK_PASSWORD_WRONG;
  return false;
}

всегда получайте сообщение о неправильном пароле. Я прочитал это php password_hash и password_verify не совпадают но я проверил хеш-строку вручную, чтобы проверить буквальную строку.

Хэш-строка: $2y$10$SwSq7OukPpN/QJ8YOdKgquJQ28fQbNY1Q3JdTFnoe.2VxD/D2RXBS.

Пароль отправить по электронной почте: /f)1c(-JG

проверено вручную:

$hash = '$2y$10$SwSq7OukPpN/QJ8YOdKgquJQ28fQbNY1Q3JdTFnoe.2VxD/D2RXBS';
$password = '/f)1c(-JG';

if (password_verify($password, $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}

печатает Неверный пароль.


person mnlfischer    schedule 13.03.2014    source источник
comment
Достаточно ли длинный столбец базы данных для хранения всего хэша без усечения?   -  person deceze♦    schedule 13.03.2014
comment
да user_password_hash VARCHAR(255) COLLATE utf8_unicode_ci ПО УМОЛЧАНИЮ NULL   -  person mnlfischer    schedule 13.03.2014
comment
Тогда не могли бы вы предоставить минимальный тестовый пример, показывающий проблему? Потому что функции password_ как таковые работают нормально, и вы выглядите правильно их используете. Однако есть много частей, которые мы здесь не видим и не можем отладить.   -  person deceze♦    schedule 13.03.2014
comment
Я могу опубликовать процесс создания отверстия, но mvc огромен. Я добавляю процесс отправки smtp. Может быть, пароль sendet неверен? Но я так не думаю, потому что это тот же результат от generate_password.   -  person mnlfischer    schedule 13.03.2014
comment
Я прошу именно минимальный пример, а не все. Попробуйте уменьшить проблему самостоятельно. Если у вас есть многоэтапный процесс, в котором что-то идет не так, попробуйте сначала сосредоточиться на этом одном и убедитесь, что он вообще работает. Затем шаг за шагом расширяйте проблему до исходной области.   -  person deceze♦    schedule 13.03.2014
comment
Господи... в теле сообщения smtp добавлена ​​/ причина, по которой я забыл n. Так что я просто подумал, что пароль был f)1c(-JG, но это был f)1c(-JG. Но вы дали мне стимул...   -  person mnlfischer    schedule 13.03.2014
comment
Ну вот. Кстати, вашего генератора паролей недостаточно. Гарантируется, что каждый пароль никогда не будет содержать одну и ту же букву дважды. Это далеко не случайный пароль и очень помогает любому злоумышленнику в случайном подборе паролей, если он знает об этом ограничении.   -  person deceze♦    schedule 13.03.2014
comment
хорошо спасибо за совет. Я создам новый генератор.   -  person mnlfischer    schedule 13.03.2014
comment
Эй, я автор сценария, который вы использовали. Просто следуйте инструкциям по установке и не меняйте код в ядре, и все будет работать нормально. пароль, отправленный по почте, ясно показывает, что вы делаете действительно очень странные вещи. НИКОГДА не отправляйте пароль по почте. Сценарий этого не делает, и для этого нет абсолютно никаких причин.   -  person Sliq    schedule 17.05.2014


Ответы (1)


Ваша переменная $hash в вашем тестовом примере недействительна и не соответствует паролю

$hash = '$2y$10$SwSq7OukPpN/QJ8YOdKgquJQ28fQbNY1Q3JdTFnoe.2VxD/D2RXBS';
$password = '/f)1c(-JG';

if (password_verify($password, $hash)) {
echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}

Когда я использовал этот код, все работает правильно

$password = '/f)1c(-JG';
$hash = password_hash($password, PASSWORD_DEFAULT, array("cost" => 10));

if (password_verify($password, $hash)) {
    echo 'Password is valid!';
} else {
     echo 'Invalid password.';
}

Я использую php 5.5.10

person mca    schedule 13.03.2014
comment
была ошибка в smtp, который отправляет неправильный пароль. - person mnlfischer; 13.03.2014
comment
@mnlfischer Извините, что? Вы не можете отправлять пароли или хэши куда угодно. Что вы имеете в виду под smtp здесь? - person Sliq; 17.05.2014
comment
@Panique Я думаю, он создает систему для входа в систему ботов :) - person Janaka R Rajapaksha; 29.05.2014