Рекурсивную функцию хеширования


Этот метод является частью моей системы входа. Я мог бы улучшить его дальше?

protected function _hashPassword($password = NULL, $rounds = 1000, $i = 1)
{
    if (! isset($password)) throw new Exception('No password set!');

    $salt   = 'K^^%/m>(|{z= $1^>%>W[=4U5*p|,E';
    $pepper = '08[)^,&%^^771^=>&,E[XP::4})h*I';

    $dinner = $salt.$password.$pepper;

    if ($i >= $rounds) return sha1($dinner);
    return sha1($this->_hashPassword($dinner, $rounds, $i+1).$password);
}


757
4
задан 30 ноября 2011 в 08:11 Источник Поделиться
Комментарии
2 ответа

Я хотел бы использовать цикл for вместо рекурсивных вызовов:

protected function _hashPassword($password = NULL, $rounds = 1000) {
if (!isset($password)) throw new Exception('No password set!');

$salt = 'K^^%/m>(|{z= $1^>%>W[=4U5*p|,E';
$pepper = '08[)^,&%^^771^=>&,E[XP::4})h*I';

$dinner = $salt . $password . $pepper;

for ($i = 0; $i < $rounds; $i++) {
$dinner = sha1($dinner . $password);
}
return $dinner;
}

От http://php.net/manual/en/functions.user-defined.php:


Можно вызывать функции PHP рекурсивно. Однако избежать
рекурсивные функции/вызовы метода с более чем 100-200 уровней рекурсии, как
он может разбить стек и вызвать прерывание текущего сценария.

Кроме того, я хотел бы использовать имя пользователя как "перец". Это сделает кашу более непредсказуемой.

5
ответ дан 30 ноября 2011 в 09:11 Источник Поделиться

Несколько замечаний на подход вы принимаете здесь:


  1. Если возможно, я хотел использовать осуществляется в хэш пароля, а не писать свой собственный мульти-раунд алгоритма хэширования. (Вот PHP библиотека для хэширования паролей).

  2. Соления подают три преимущества. Во-первых, и менее важно, это означает, что если кто-то получает базу данных, но не приложения код, это немного труднее для них, чтобы взломать ваши пароли. Во-вторых, выбирая соли с помощью специальных символов в нем, вы сделаете ваши хэши менее восприимчивы к радужной таблице атаки. В-третьих, используя различные хэш для каждого пользователя, злоумышленник пытается взломать каждый пароль отдельно, а не в состоянии проверить всю базу данных самых распространенных паролей за один раз. Ваши соления подход обеспечивает первый и второй, а не третий. Как уже упоминалось, имя пользователя является хорошим кандидатом для уникального идентификатора, чтобы включить как часть соли.

На сам код:


  1. Почему по умолчанию параметр $пароль поле, а затем проверить, чтобы увидеть, если он установлен? Если он должен быть установлен по умолчанию. Вы наверное также хотите, чтобы проверить, используя пустые не задается.

  2. Как стиль мне нравится вытягивать константы как $соль и $перец топ класса, а не их скрытые встроенные в отдельные методы. Я найти попадая в привычку всегда делать это уменьшает вероятность случайного дублирования их в несколько методов.

5
ответ дан 5 декабря 2011 в 01:12 Источник Поделиться