PHP Забыли пароль - PullRequest
       71

PHP Забыли пароль

36 голосов
/ 05 июля 2011

У меня небольшой веб-сайт сообщества, и мне нужно реализовать функцию забытого пароля. В настоящее время я храню пароли в БД, зашифрованные с помощью MD5.

Можно ли сортировать «дешифровать» и отправлять его пользователю по электронной почте или мне нужна страница для сброса пароля?

Ответы [ 12 ]

134 голосов
/ 05 июля 2011

MD5-хэшированный пароль необратим. (MD5 хэширует, а не шифрует, так что есть небольшая разница). И да вы определенно захотите предоставить процесс сброса пароля (а не просто отправить пароль по электронной почте).

Чтобы обеспечить высокий уровень рабочего процесса для безопасного сброса пароля ...

  1. Когда пользователь просит сбросить свой пароль, заставьте его ввести свой адрес электронной почты
  2. Не указывайте, был ли этот адрес электронной почты действительным или нет (просто скажите им, что письмо было отправлено). Это открыто для обсуждения, так как снижает удобство использования (т. Е. Я понятия не имею, на какое письмо я зарегистрировался), но предлагает меньше информации людям, пытающимся собрать информацию о том, какие письма действительно зарегистрированы на вашем сайте.
  3. Сгенерируйте токен (возможно, хэшируйте временную метку с солью) и сохраните ее в базе данных в записи пользователя.
  4. Отправьте электронное письмо пользователю вместе со ссылкой на страницу сброса http s (токен и адрес электронной почты в URL).
  5. Используйте токен и адрес электронной почты для подтверждения пользователя.
  6. Пусть они выберут новый пароль, заменив старый.
  7. Кроме того, хорошей идеей является истечение срока действия этих токенов через определенный промежуток времени, обычно через 24 часа.
  8. При желании запишите, сколько «забытых» попыток произошло, и, возможно, реализуйте более сложные функции, если люди запрашивают тонну писем.
  9. При желании запишите (в отдельной таблице) IP-адрес лица, запрашивающего сброс. Увеличьте счет с этого IP. Если оно когда-нибудь достигнет более, чем, скажем, 10 ... Игнорируйте их будущие запросы.

Чтобы немного подробнее рассказать о хешировании ...

Когда вы хэшируете значение, такое как пароль, с помощью функции md5 () в PHP, окончательное значение для этого пароля будет одинаковым, независимо от того, на каком сервере вы его запускаете. (Таким образом, есть одно различие, которое мы можем сразу увидеть между хешированием и шифрованием ... В этом нет никакого личного / открытого ключа).

Здесь вы увидите, как люди упоминают об уязвимости к радужным таблицам . Очень простое объяснение радужной таблицы ... Вы md5 () хешируете несколько слов в словаре (слабые пароли), чтобы получить их хэшированные значения md5 (). Поместите их в таблицу базы данных (радужную таблицу).

Теперь, если вы скомпрометировали базу данных веб-сайта, вы можете запустить хешированные пароли пользователей к вашей радужной таблице, чтобы (по сути) «перевернуть» хэш обратно к паролю. (Вы на самом деле не «меняете» хеш… Но вы поняли).

Вот где лучше всего "солить" ваши пароли. Это означает (опять же, очень простая идея здесь), что вы добавляете случайное значение к паролям пользователей до того, как вы его хешируете. Теперь, когда радужная таблица запускается для вашей базы данных, ее не так просто «перевернуть», поскольку хэш md5 () «password» отличается от «password384746».

Вот хорошая SO Q / A, которая должна помочь. Безопасный хеш и соль для паролей PHP

9 голосов
/ 22 мая 2013

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

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

Подводя итог:

$token = md5(microtime (TRUE)*100000);
$tokenToSendInMail = $token;
$tokenToStoreInDB = hash($token);

где хэш - алгоритм хеширования.

7 голосов
/ 05 июля 2011

Нет, MD5 необратим. Смысл хэширования паролей заключается в том, чтобы злоумышленник, получивший доступ к вашей базе данных, не мог получить доступ ко всем паролям.

Тем не менее, MD5 (особенно несоленый MD5) обычно можно атаковать с помощью радужного стола . В целях безопасности лучше использовать bcrypt .

3 голосов
/ 25 марта 2016

Как отметил Маркус Рид, в 2015/2016 году, если у вас версия PHP> = 5.5, не используйте MD5, password_hash () и password_verify () обеспечивают простое и безопасное хеширование вашего пароля с возможностью определения стоимости иавтоматически подсчитывает хеш

3 голосов
/ 05 июля 2011

Лучшее, что вы можете сделать, это попросить людей при регистрации указать свой адрес электронной почты.Затем, если они забудут, имейте ссылку для забытого пароля, которая сбрасывает их пароль со случайным значением, которое им отправляется по электронной почте, чтобы они могли получить доступ, а затем сменили свой пароль на что-то более запоминающееся.Таким образом, вам не нужно ставить под угрозу безопасность.У вас может быть ссылка, в которую им просто нужно ввести свое имя пользователя, но для большей безопасности у вас должен быть вопрос и ответ или запоминающееся слово.

3 голосов
/ 05 июля 2011

Вы не можете расшифровать пароль, и вы даже не должны рассматривать отправку пароля пользователю через открытый текст.(Это способ № 1, чтобы я никогда больше не использовал сайт; это ГИГАНТСКАЯ дыра в безопасности.) Предоставьте страницу сброса пароля, которая вызывается ссылкой, содержащей связанный со временем ключ, который отправляется на электронную почту восстановления пароля пользователя.;это современный уровень восстановления пароля.

2 голосов
/ 03 июня 2015

Используйте встроенные в php пароли_verify и password_hash.

2 голосов
/ 05 июля 2011

Напишите страницу, которая принимает md5 и адрес электронной почты в качестве параметра get, и ищет в db адрес электронной почты и пароль md5'd. Следуя заметкам Джареда Кобба, вы должны встать на правильный путь. я просто добавил несколько примеров

например, URL для отправки http://yourdomain.com/resetpassword.php?code=md5codesentviaemail

 $code = isset($_GET['code']) ? $_GET['code'] : '';
    $email = isset($_GET['email']) ? $_GET['email'] : '';
$checkPw = '';

    if(empty($code) || empty($email))
    {
     die();
    }
    $sqlQuery = 'SELECT * FROM users WHERE email = "'.$email.'";
//remember to check for sql injections
    //then get the results as an array, i use a database class eg $user

    if(!empty($user['password']))
    {
     $checkPw = md5($user['password']);
    }else
    {
     die();
    }

    if($checkPw !== $code)
    {
     die();
    }else
    {
    //display form for user to change password
    }

этого должно быть достаточно для того, чтобы вы знали, что пользователь является действительным пользователем, и измените его пароль

2 голосов
/ 05 июля 2011

MD5 предназначен для одностороннего хеширования.Вам нужно будет восстановить их пароль.

1 голос
/ 05 июля 2011

MD5 - односторонняя функция.Вы не можете расшифровать это.Так что вам нужно иметь страницу сброса пароля.

...