#php #url #encryption #hyperlink #md5
#php #url #шифрование #гиперссылка #md5
Вопрос:
Мне было интересно, будет ли использование substr(md5(rand()), 0, 17);
достаточно безопасным для ссылки сброса пароля? Если бы я должен был сгенерировать более длинную строку, это сделало бы ее более безопасной? Является ли MD5 вообще безопасным? Или я должен это сделать $token = sha1(uniqid($username, true));
?
Комментарии:
1.
md5
нормально, ноrand()
, скорее всего, нет, в зависимости от вашегоsrand(...)
…2. Есть ли у вас какое-либо конкретное ограничение длины, потому что существует большая разница между sha1 и подмножеством md5 с 17 символами.
3. Просто что-нибудь достаточно безопасное @Jack
Ответ №1:
Использование substr()
or md5()
является вторичным по отношению к использованию rand()
.
Весь смысл использования токенов сброса пароля заключается в том, что они непредсказуемы и rand()
, как известно, слабы из-за базовой модели LCG.
Было бы лучше использовать вместо этого системный источник энтропии, например:
$rand = openssl_random_pseudo_bytes(8); // take 8 random bytes
$token = substr(md5($rand), 0, 17);
Он принимает байты из случайного источника системы, например /dev/urandom
, в Linux или соответствующей системе для Windows.
Обратите внимание, что если у вас нет каких-либо конкретных ограничений по размеру, вы можете также выбрать полный sha1()
вывод и взять 16 случайных байтов.
Кроме того, вы должны относиться к токенам сброса пароля так, как если бы они были (временными, ограниченными по времени) паролями, когда вы храните их в своей базе данных; Я бы посоветовал отправить вышеуказанный токен пользователю, а затем использовать password_hash()
, прежде чем записывать их в базу данных. На более позднем этапе вы проверяете данный токен (при условии, что он не истек), используя password_verify()
.
Комментарии:
1. При выполнении
echo $token
я получаюWarning: md5() expects at most 2 parameters, 3 given in /Users/matt/Desktop/Likes/forgot/forgot.php on line 18
иWarning: substr() expects at least 2 parameters, 1 given in /Users/matt/Desktop/Likes/forgot/forgot.php on line 18
2. Так будет ли это менее непредсказуемо? Могу ли я сохранить используемый токен в БД и проверить, использовались ли они? Это было бы необходимо? Также отличный ответ.
3. Токены сброса @user3100859 должны использоваться только один раз, а затем уничтожаться; кроме того, прочитайте последний раздел моего ответа относительно хранилища токенов сброса.
4. Так что, также хэшируйте токен, а затем отправьте его? Также является ли 30 минут достаточным временем для сброса токенов?
5. @user3100859 Кроме того, как упоминалось ранее, если у вас нет ограничений по размеру .. сделайте его большим 🙂
Ответ №2:
Для случайного хэша это достаточно безопасно. Вашей проблемой могут быть коллизии, и первые 17 символов MD5 для случайного значения должны быть достаточно случайными, чтобы избежать их в проекте с малой нагрузкой.
Я бы выбрал uniqid()
с дополнительной энтропией rand()
(и, возможно, даже mt_rand()
).
Однако я бы не стал использовать MD5
or SHA1
для хранения ваших паролей.
Ответ №3:
Я не вижу смысла в использовании substr(), если у вас нет какого-то ограничения длины, которое имеет смысл. Чем больше ключ, тем лучше. В общем, рекомендуется использовать хэши в их полной форме. Если бы MD5 считался «достаточно безопасным», он уже был бы урезан. Чем больше обрезка, тем выше вероятность столкновения.
Я предпочитаю использовать GUID для ссылок на сброс пароля. Идентификаторы GUID так же непредсказуемы (и безопасны), как хэш случайного числа MD5, и оба они являются 128-битными значениями.
Обязательно используйте метку времени истечения срока действия для токена сброса. Обычно я использую 24 часа.
Не используйте системные часы или какие-либо производные. Вы хотите убедиться, что хакер не сможет сбросить пароль другого пользователя при записи метки времени, а затем угадать токен сброса, чтобы сгенерировать URL-адрес сброса. Поэтому не используйте значения, основанные непосредственно на системных часах или на чем-либо еще предсказуемом.
Вы также должны использовать количество неудач / максимальное количество повторных попыток для одного токена сброса пароля, как и для обычных логинов, чтобы ограничить количество возможных атак. Если хакер знает идентификатор пользователя и пытается угадать URL для сброса пароля, вы должны отслеживать количество попыток для данного идентификатора пользователя при попытке входа в систему и соответствующим образом заблокировать учетную запись. Максимум хакер получает 3 попытки, затем блокирует учетную запись на час. В этом случае substr() MD5 по-прежнему довольно безопасен.