Работа с потерянными паролями

Задача
Необходимо предоставить пароль пользователю, заявившему о его утрате.

Решение
Сгенерируйте новый пароль и пошлите его по адресу электронной почты пользователя (предварительно сохраненному вами в файле):

// генерируем новый пароль
$new_password = '';
$i = 8;
while ($i--) { $new_password .= chr(mt_rand(33,126)); }
// зашифровываем новый пароль
$encrypted_password = crypt($new_password);
// сохраняем новый зашифрованный пароль в базе данных
$dbh->query('UPDATE users SET password = ? WHERE username = ?',
array($encrypted_password,$username));
// шлем письмо пользователю с паролем в виде обычного текста
mail($email,"New Password","Your new password is $new_password");

Обсуждение
Если пользователь забывает свой пароль, а пароли хранятся в соответствии с рекомендациями рецепта 14.4, то невозможно предоставить забытый пароль. Односторонняя природа функции crypt() не позволяет восстановить исходный пароль.
Вместо этого генерируется новый пароль и посылается по существующему адресу. Если вы посылаете новый пароль по адресу, которого нет в файле данного пользователя, то у вас нет способа проверить, действительно ли этот адрес принадлежит указанному пользователю.


Это может быть попыткой атаки с целью получения пароля и имитацией реального пользователя.

Поскольку почтовое сообщение с новым паролем не зашифровано, то программа в разделе «Решение» не включает в него имя пользователя, чтобы как-то уменьшить вероятность использования украденного па-роля атакующим, перехватившим почтовое сообщение. Чтобы совсем исключить обнаружение пароля в письме, разрешите пользователю идентифицировать себя без пароля, отвечая на один или более личных вопросов (ответы на которые находятся в файле пользователя). Вопросы могут быть типа: «Как звали вашего первого питомца?», или «Какую фамилию носила ваша мать в девичестве?», или еще что-нибудь такое, что злонамеренный атакующий вряд ли знает. Если пользователь дает правильные ответы на ваши вопросы, то можно позволить ему указать новый пароль.
Один из способов добиться компромисса между безопасностью и читаемостью состоит в том, чтобы генерировать пароль пользователя, состоящий из реальных слов, перемежающихся числами.

$words =
array('dished','mother','basset','detain','sudden','fellow','logged','sonora',
'earths','remove','dustin','snails','direct','serves','daring','cretan',
'chirps','reward','snakes','mchugh','uphold','wiring','gaston','nurses',
'regent','ornate','dogmas','singed','mended','hinges','latent','verbal',
'grimes','ritual','drying','hobbes','chests','newark','sourer','rumple');
mt_srand((double) microtime() * 1000000);
$word_count = count($words);
$password = sprintf('%s%02d%s', $words[mt_rand(0,$word_count - 1)],
mt_rand(0,99), $words[mt_rand(0,$word_count - 1)]);
print $password;

Этот фрагмент программы генерирует пароли из двух шестибуквенных слов с двумя цифрами между ними, наподобие mother43hinges или verbal08chirps.


Эти пароли длинные, но слова в них делают пароли легкими для запоминания.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела PHP на эту тему:
Не храните пароли на своем сайте
Обнаружение SSL-соединения
Проверка данных с помощью хеширования
Проверка надежности пароля
Совместное использование зашифрованных данных с другим веб-сайтом

Вернуться в раздел: PHP / 14. Шифрование и безопасность