Вопрос

Я искал эффективный алгоритм, который мог бы дать мне точное представление о том, насколько надежен пароль.

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

Это было полезно?

Решение

Это привело к тому, что у меня появилось много полезных советов по работе с паролями в PHP / MySQL. Представленные здесь идеи, как правило, не мои, но лучшие из того, что я нашел на сегодняшний день. <ч> Убедитесь, что вы используете SSL для всех операций, связанных с пользовательской информацией. Все страницы, содержащие эти формы, должны проверять, что они вызываются через HTTPS, и отказываться работать в противном случае.

Вы можете устранить большинство атак, просто ограничив количество неудачных входов в систему.

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

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

Также убедитесь, что вы возвращаете одно и то же сообщение в случае сбоя при слишком большом количестве входов в систему с действительным паролем и сбоя при слишком большом количестве входов в систему и неверного пароля. Предоставление другого сообщения позволит злоумышленникам определить действительные пароли пользователей. Достаточное количество пользователей, когда им придется сбросить свой пароль, просто вернет его на прежний уровень.

К сожалению, ограничение количества входов в систему на один IP-адрес нецелесообразно. Несколько провайдеров, таких как AOL и большинство компаний, используют свои веб-запросы. Введение этого ограничения эффективно устранит этих пользователей. <ч> Я обнаружил, что проверка словарных слов перед отправкой неэффективна, так как нужно либо отправить клиенту словарь в javascript, либо отправить ajax-запрос на изменение поля. Я делал это некоторое время, и это работало нормально, но мне не нравился трафик, который он генерировал.

Проверка на наличие слабых по своей сути паролей минус слова из словаря - это практическая клиентская сторона с небольшим простым JavaScript.

После отправки я проверяю слова словаря и имя пользователя, содержащее пароль, и наоборот на стороне сервера. Очень хорошие словари легко загружаются, и тестирование на них просто. Здесь есть один недостаток: для проверки словарного слова необходимо отправить запрос к базе данных, которая снова содержит пароль. Способ, которым я смог обойти это, заключался в том, чтобы зашифровать свой словарь заранее, используя простое шифрование, и SALT в конечной позиции, а затем проверить зашифрованный пароль. Не идеально, но лучше, чем обычный текст, и только по проводам для людей на ваших физических машинах и в подсети.

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

РЕДАКТИРОВАТЬ: я бы сейчас рекомендовал использовать PhPass вместо своей собственной функции здесь или просто забудьте о входах пользователей в систему и используйте вместо этого OpenID .

function password_crypt($email,$toHash) {
  $password = str_split($toHash,(strlen($toHash)/2)+1);
  return hash('sha256', $email.$password[0].SALT.$password[1]); 
}

Мой Jqueryish измеритель пароля на стороне клиента. Цель должна быть div. Его ширина будет меняться от 0 до 100, а цвет фона будет меняться в зависимости от классов, обозначенных в скрипте.

Другие советы

По сути, вы хотите предотвратить основные типы атак

  • Словарные атаки
  • Атаки грубой силой

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

Быстрый поиск в Google выявил решения, которые учитывают атаки методом перебора (сложный пароль), но не атаки по словарю.Измеритель надежности пароля PHP от этот список проверяющих на прочность запускает проверку на стороне сервера, поэтому ее можно было бы расширить для проверки словаря.

Редактировать:

Кстати...вам также следует ограничить количество попыток входа в систему для каждого пользователя.Это сделает оба типа атак менее вероятными.Эффективным, но не удобным для пользователя способом является блокировка учетной записи после X неудачных попыток и требование сброса пароля.Более удобным для пользователя, но требующим больше усилий, является сокращение времени между попытками входа в систему.Вы также можете потребовать КАПЧА после первых нескольких попыток входа в систему (чего требует Stack Overflow после слишком большого количества правок или для очень новых пользователей).

В основном вы, вероятно, хотите использовать регулярные выражения для проверки длины и сложности пароля.

Хороший пример, который делает это с использованием JavaScript, можно найти здесь:

http://marketingtechblog.com/programming/javascript-password-strength/

Как указал на это Дарен Швенке, вам лучше поработать над безопасностью самостоятельно, а не передавать это в руки пользователя.

Но полезно дать пользователю несколько советов о том, насколько надежен его пароль, потому что лучшим способом получить пароль по-прежнему остается социальная разработка.

Таким образом, вы можете взломать небольшой клиентский скрипт, который проверяет надежность пароля пользователя в качестве индикатора вежливости в режиме реального времени.Он ничего не блокирует, но дарит ему приятное теплое ощущение, когда становится зеленым :-)

В основном то, что вы должны проверить, - это commom sense :проверьте, содержит ли пароль буквы, цифры и неалфавитные символы в разумных количествах.

Вы можете очень легко взломать свой собственный алгоритм :просто сделайте отметку 10/10 :

  • 0 - пароль нулевой длины;
  • +2 за каждые 8 символов в пароле (предполагается, что 15 символов безопасной длины);
  • +1 за использование буквы, +2 за использование 2 букв;
  • +1 за использование числа, +2 за использование 2 чисел;
  • +1 за использование неалфавитных символов, +2 за 2.

Вам не нужно проверять наличие божественных паролей (есть ли там заглавные буквы, где расположены специальные символы и т.д.), ваши пользователи не относятся к банковской / военной / секретной службе / киноиндустрии monthy python, не так ли?

Вы можете закодировать это за час, не имея сумасшедших навыков работы с javascript.

И в любом случае, подтвердите пароль и переместите весь код безопасности на сторону сервера.Если вы можете делегировать аутентификацию (например, :open ID), еще лучше.

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

Вы можете определить много разных уровней прочности, если вы используете разные ограничения, или вы можете определить другое значение для конкретных критериев. Например, если пароль имеет 5 символов, мы добавляем 1, но если он получил 10, то мы добавляем 2.

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

Длина (от 8 до 12 в порядке, чем больше, тем лучше) Содержит строчную букву Содержит заглавную букву Заглавная буква НЕ первая. Содержит номер Содержит символы последний символ НЕ является символом, похожим на человека (например:. или!) Не похоже на словарное слово. В некоторых хитрых паролях есть библиотека заменителей слов и букв (например, Библиотека -> g1; @ ry)

Надеюсь, что поможет.

Не катайся!

Эксперты по криптографии не одобряют криптографию по принципу «сделай сам» По причинам, которые должны быть очевидны.

По тем же причинам не следует пытаться найти собственное решение проблемы измерения надежности пароля; это очень большая криптографическая проблема.

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

Это сложная проблема

Существует значительная сложность, связанная с проблемой измерения надежности пароля. Чем больше исследований я выполняю по этому вопросу, тем больше понимаю, что это «однонаправленный» вопрос. проблема; то есть нельзя измерить «сложность» (вычислительная стоимость) взлома пароля эффективно . Скорее, более эффективно предоставлять требования к сложности и измерять способность пароля соответствовать им.

Когда мы рассмотрим проблему логически, «индекс хрупкости» не имеет особого смысла, так удобно, как кажется. Есть так много факторов, которые управляют вычислениями, большинство из которых относятся к вычислительным ресурсам, выделенным для процесса взлома, что является непрактичным.

Представьте себе, что Джон Потрошитель (или похожий инструмент) сопоставляет рассматриваемый пароль; Чтобы взломать приличный пароль могут потребоваться дни, месяцы, чтобы взломать хороший пароль, и пока солнце не сгорит, чтобы взломать исключительный пароль. Это непрактичный способ измерения надежности пароля.

Подход к решению проблемы с другой стороны гораздо более управляем: если мы представим набор требований к сложности, можно очень быстро оценить относительную надежность пароля. Очевидно, что предъявляемые требования к сложности должны со временем развиваться, но существует гораздо меньше переменных, которые необходимо учитывать, если мы подходим к проблеме таким образом.

Жизнеспособное решение

В Openwall имеется отдельная утилита под названием passwdqc (предположительно , обозначая Проверка качества пароля ). Разработчик Openwall, Solar Designer, действительно является добросовестным экспертом в области криптографии (его работы говорят сами за себя), и поэтому он квалифицирован как автор такого инструмента.

Для моего конкретного варианта использования это гораздо более привлекательное решение, чем использование непродуманного фрагмента JavaScript, живущего в каком-то темном уголке Интернета.

Определение параметров для ваших конкретных потребностей - самая сложная часть. Реализация является простой частью.

Практический пример

Я предлагаю простую реализацию в PHP, чтобы обеспечить быстрый старт. Применяются стандартные заявления об отказе от ответственности.

В этом примере предполагается, что мы вводим полный список паролей в скрипт PHP. Само собой разумеется, что если вы делаете это с реальными паролями (например, с паролями, сброшенными из диспетчера паролей), следует соблюдать крайнюю осторожность в отношении обработки паролей. Простая запись незашифрованного дампа паролей на диск ставит под угрозу безопасность ваших паролей!

<код> passwords.csv :

"Title","Password"
"My Test Password","password123"
"Your Test Password","123456!!!"
"A strong password","NFYbCoHC5S7dngitqCD53tvQkAu3dais"

<код> паролем check.php :

<?php

//A few handy examples from other users:
//http://php.net/manual/en/function.str-getcsv.php#117692

$csv = array_map('str_getcsv', file('passwords.csv'), [',']);

array_walk($csv, function(&$a) use ($csv) {
    $a = array_combine($csv[0], $a);
});

//Remove column header.

array_shift($csv);

//Define report column headers.

$results[] = [
    'Title',
    'Result',
    'Exit Code',
];

$i = 1;

foreach ($csv as $p) {
    $row['title'] = $p['Title'];

    //If the value contains a space, it's considered a passphrase.

    $isPassphrase = stristr($p['Password'], ' ') !== false ? true : false;

    $cmd = 'echo ' . escapeshellarg($p['Password']) . ' | pwqcheck -1 min=32,24,22,20,16 max=128';

    if ($isPassphrase) {
        $cmd .= ' passphrase=3';
    }
    else {
        $cmd .= ' passphrase=0';
    }

    $output = null;
    $exitCode = null;

    $stdOut = exec($cmd, $output, $exitCode);

    //Exit code 0 represents an unacceptable password (not an error).
    //Exit code 1 represents an acceptable password (it meets the criteria).

    if ($exitCode === 0 || $exitCode === 1) {
        $row['result'] = trim($stdOut);
        $row['exitCode'] = $exitCode;
    }
    else {
        $row['result'] = 'An error occurred while calling pwqcheck';
        $row['exitCode'] = null;
    }

    $results[$i] = $row;

    $i++;
}

$reportFile = 'report.csv';

$fp = @fopen($reportFile, 'w');

if ($fp !== false) {
    foreach ($results as $p) {
        fputcsv($fp, $p);
    }

    fclose($fp);
}
else {
    die($reportFile . ' could not be opened for writing (destination is not writable or file is in use)');
}

exit;

Результирующий report.csv :

Title,Result,"Exit Code"
"My Test Password","Bad passphrase (too short)",1
"Your Test Password","Bad passphrase (too short)",1
"A strong password",OK,0

Упаковочная-Up

Мне еще предстоит найти более полное решение в Интернете; Излишне говорить, что я приветствую любые другие рекомендации.

Очевидно, что этот подход не идеален для определенных случаев использования (например, «измеритель надежности пароля», реализованный «на стороне клиента»). Несмотря на это, было бы тривиально сделать AJAX-вызов к ресурсу на стороне сервера, который возвращает ответ «пройдено / не выполнено», используя подход, описанный выше, но такой

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top