Проверка надежности пароля

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

Решение
Проверьте выбранный пользователем пароль с помощью функции pc_passwordcheck(), показанной далее в примере 14.1. Например:

if ($err = pc_passwordcheck($_REQUEST['username'],$_REQUEST['password'])) {
print "Bad password: $err";
// Предлагаем пользователю выбрать другой пароль
}

Обсуждение
Функция pc_passwordcheck(), показанная в примере 14.1, выполняет определенные проверки выбранных пользователем паролей на предмет легкости их угадывания. Она возвращает строку с описанием проблемы, если пароль не отвечает критерию. Пароль должен иметь длину, равную минимум 6 символам, и быть составленным из букв верхнего и нижнего регистра, цифр и специальных символов. Пароль не может содержать имя пользователя в обычном или обратном порядке следования символов. Кроме того, пароль не должен содержать слов из словаря. Имя файла для списка слов, используемых при словарной проверке, находится в переменной $word_file.

Проверки пароля на имя пользователя или на слова из словаря применяются и к вариантам пароля, в которых буквы заменены похожими на них цифрами.


Например, если предоставлен пароль w0rd$%, то функция также проверяет на имя пользователя и словарные слова строку word$%. Символ «0» превращается в символ «o». Аналогично «5» превращается в «s», «3» в «e», а «1» и «!» в «l» (el).

Пример 14.1. pc_passwordcheck()
function pc_passwordcheck($user,$pass) {
$word_file = '/usr/share/dict/words';
$lc_pass = strtolower($pass);
// также проверяем пароль с цифрами и знаками пунктуации,
// заменяющими буквы
$denum_pass = strtr($lc_pass,'5301!','seoll');
$lc_user = strtolower($user);
// пароль должен состоять минимум из шести символов
if (strlen($pass) < 6) {
return 'The password is too short.';
}// пароль не может быть именем пользователя
// (или перевернутым именем пользователя)
if (($lc_pass == $lc_user) || ($lc_pass == strrev($lc_user)) ||
($denum_pass == $lc_user) || ($denum_pass == strrev($lc_user))) {
return 'The password is based on the username.';
}
// подсчитываем, сколько в пароле символов верхнего
// и нижнего регистра и цифр
$uc = 0; $lc = 0; $num = 0; $other = 0;
for ($i = 0, $j = strlen($pass); $i < $j; $i++) {
$c = substr($pass,$i,1);
if (preg_match('/^[[:upper:]]$/',$c)) {
$uc++;
} elseif (preg_match('/^[[:lower:]]$/',$c)) {
$lc++;
} elseif (preg_match('/^[[:digit:]]$/',$c)) {
$num++;
} else {
$other++;
}
}
// в пароле должно быть более двух символов,
// по крайней мере, двух различных типов
$max = $j - 2;
if ($uc > $max) {
return "The password has too many upper case characters.";
}
if ($lc > $max) {
return "The password has too many lower case characters.";
}
if ($num > $max) {
return "The password has too many numeral characters.";
}
if ($other > $max) {
return "The password has too many special characters.";
}
// пароль не должен содержать слов из словаря
if (is_readable($word_file)) {
if ($fh = fopen($word_file,'r')) {
$found = false;
while (! ($found || feof($fh))) {
$word = preg_quote(trim(strtolower(fgets($fh,1024))),'/');
if (preg_match("/$word/",$lc_pass) ||
preg_match("/$word/",$denum_pass)) {
$found = true;
}
}
fclose($fh);
if ($found) {
return 'The password is based on a dictionary word.';}
}
}
return false;
}.



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

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

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