password_hash и password_verify возвращают false

У меня есть следующий пароль:

123

Теперь я хеширую это, и он возвращает следующий ключ:

$2y$10$rSq.2M7Ikc.QPhVtYlp1Nu8HI.Eq5fUgVWn25J

Теперь я пытаюсь проверить тот же ключ, используя:

return password_verify(123, $2y$10$rSq.2M7Ikc.QPhVtYlp1Nu8HI.Eq5fUgVWn25J);

однако это возвращает false.

Кто-нибудь может сказать мне, почему?

Обновить

это мой полный код:

<?php
/**
 * Created by JetBrains PhpStorm.
 * User: Marc
 * Date: 14-12-13
 * Time: 13:56
 * To change this template use File | Settings | File Templates.
 */
class Security {
    /**
     * @param $string
     * @return mixed
     */
    public function encrypt($string) {
        return password_hash($string, PASSWORD_DEFAULT);
    }

    /**
     * @param $string
     * @param $hash
     * @return mixed
     */
    public function validate($string, $hash) {
        return password_verify($string, $hash);
    }
}

    $hash = $this->db->template("SELECT password FROM User WHERE username = '".$username."'", READ_FROM_QUERY)['password'];
$validate =  $this->getSecurity()->validate($password, $hash);

Я пытаюсь вставить следующую строку:

Helloworld

Однако $validate = false;

Пароль вернулся к $2y$10$VbicsFaGN9d3ggQTNYIto.Bp6x/rbjpsBe2kneEhJ9oP2KdPsZ7hy

Если я попытаюсь перефразировать его, он вернет одно и то же значение, поэтому они должны быть равны друг другу, так почему он возвращает false?!??!

Также возвращает false

$validate =  $this->getSecurity()->validate((string)$password, (string)$hash);

person Marc Rasmussen    schedule 10.01.2014    source источник
comment
Попробуйте передать пароль в password_verify() в виде строки   -  person Mark Baker    schedule 10.01.2014
comment
Как вы сгенерировали этот хэш? password_verify() работает только с password_hash() хешированными паролями?!?   -  person loveNoHate    schedule 10.01.2014
comment
Хорошо, позвольте мне попробовать перефразировать мой вопрос   -  person Marc Rasmussen    schedule 10.01.2014
comment
@MarkBaker Можете ли вы более конкретно взглянуть на мое обновление?   -  person Marc Rasmussen    schedule 10.01.2014
comment
@MarkBaker, не имеет значения, передаются ли они как строка или целое число, потому что они все равно будут преобразованы в строку. Даже передача Helloworld без кавычек работает корректно (хотя выдает предупреждение о неопределенной переменной).   -  person Mike    schedule 10.01.2014


Ответы (1)


Для вашего первого примера с паролем 123 проблема в том, что вы усекаете хэш.

$settings = array('cost' => 10, 'salt' => 'rSq.2M7Ikc.QPhVtYlp1Nu');                                        
echo password_hash('123', PASSWORD_BCRYPT, $settings);
// $2y$10$rSq.2M7Ikc.QPhVtYlp1Nu8HI.Eq5fUgVWn25J/WWUma/RrNWKFay // What is echoed
// $2y$10$rSq.2M7Ikc.QPhVtYlp1Nu8HI.Eq5fUgVWn25J                // Your hash

Я бы предположил, что столбец вашей базы данных имеет максимальную длину 45 символов, и поэтому он усекает его.

Для второй строки проблема в том, что где-то в строке вы конвертируете пароль в нижний регистр.

// Uppercase 'H'
$settings = array('cost' => 10, 'salt' => 'VbicsFaGN9d3ggQTNYIto.');
echo password_hash('Helloworld', PASSWORD_BCRYPT, $settings);
// $2y$10$VbicsFaGN9d3ggQTNYIto.qFAer7kUmKmcy6y9RCNzaaKD7fJraba

// Lowercase 'h'
$settings = array('cost' => 10, 'salt' => 'VbicsFaGN9d3ggQTNYIto.');
echo password_hash('helloworld', PASSWORD_BCRYPT, $settings);
// $2y$10$VbicsFaGN9d3ggQTNYIto.Bp6x/rbjpsBe2kneEhJ9oP2KdPsZ7hy

Поэтому, когда вы пытаетесь проверить с помощью Helloworld, он вернет false, потому что хэш предназначен для helloworld.

Вам действительно нужно быть более осторожным, потому что обе эти ошибки действительно небрежны. И обратите внимание, вы НИКОГДА не должны преобразовывать пароли в определенный регистр (верхний или нижний), потому что это значительно их ослабляет.

person Mike    schedule 10.01.2014
comment
Это может быть актуально, начиная с php.net/crypt --- Стандартная крипта на основе DES( ) возвращает соль в качестве первых двух символов вывода. Он также использует только первые восемь символов строки str, поэтому более длинные строки, начинающиеся с тех же восьми символов, будут генерировать тот же результат (при использовании одной и той же соли). - person Funk Forty Niner; 10.01.2014
comment
@ Fred-ii- Интересно ... однако password_hash сейчас использует только bcrypt (обратите внимание, что строка начинается с $2y$). - person Mike; 10.01.2014
comment
Я думал, что это может быть такая же или похожая ситуация. - person Funk Forty Niner; 10.01.2014
comment
@ Fred-ii- Ну, это говорит о хэшируемой строке, а не о самом хеше. Так что в любом случае это не усекло бы хеш. Например, Microsoft в течение многих лет усекала пароли в Hotmail до 16 символов. Если бы у вас был более длинный пароль, они использовали бы только первые 16 символов, чтобы вы могли ввести случайные символы для всего, что больше 16, и войти. Теперь они фактически вынуждают использовать пароль из 16 символов. или менее. Какие сумасшедшие решили, что это лучший способ обеспечить безопасность? Я думаю, что это то же самое для их ОС. - person Mike; 10.01.2014
comment
Я слышал, что Hotmail хранит пароли в виде простого текста. Не помню, где я это читал, но мне почти хочется в это поверить. - person Funk Forty Niner; 10.01.2014
comment
@Fred-ii- Я suuuuure надеюсь, что нет... Я не удивлюсь, если они привыкли к этому, но за эти годы так много компаний сохранили их пароли в несоленых md5 или sha1 (или даже в виде обычного текста) и были украдены, что я, честно говоря, не вижу, чтобы Microsoft все еще хранила их в виде простого текста. Если бы это когда-нибудь просочилось, представьте себе судебные иски. Однако, с учетом сказанного, ограничение длины, особенно чего-то настолько короткого, просто кричит о простом тексте. - person Mike; 10.01.2014
comment
Все во имя экономии нескольких драгоценных байтов памяти, что было первоначальным намерением в далеком прошлом. Несколько лет назад я чуть не потерял учетную запись Hotmail, и это меня чертовски напугало. Я был удачлив и быстр в розыгрыше; это довольно длинная история, но в двух словах, я дождался подходящего момента, чтобы получить электронное письмо для сброса пароля, отправленное на мою связанную учетную запись, и сразу же изменил его. И да, если бы это было так, и это когда-нибудь просочилось бы, мы бы купались в большом количестве денег ;-) - person Funk Forty Niner; 10.01.2014
comment
@ Fred-ii- Только DES усекает строку после 8 символов, BCrypt использует до 72 символов пароля, хотя не жалуется, если вы передаете больше символов. - person martinstoeckli; 10.01.2014
comment
Я бы предположил, что столбец вашей базы данных имеет максимальную длину 45 символов, и поэтому он усекает его. Это было именно то, что происходило!! Спасибо - person Marc Rasmussen; 10.01.2014