Лучшие практики PHP для аутентификации пользователей и безопасности паролей - PullRequest
48 голосов
/ 26 октября 2009

Каковы лучшие текущие библиотеки / методы для аутентификации пользователей без использования CMS или тяжелой платформы?

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

Ответы [ 8 ]

30 голосов
/ 26 октября 2009

OpenID - это метод аутентификации пользователей на основе их существующих учетных записей в общих веб-службах, таких как Yahoo, Google и Flickr.

Вход на ваш сайт основан на успешном входе на удаленный сайт.

Вам не нужно хранить конфиденциальную информацию о пользователях или использовать SSL для защиты логинов пользователей.

Текущую версию библиотеки PHP можно найти здесь .

13 голосов
/ 10 мая 2015

Реализация аутентификации пользователя безопасно , не полагаясь на каркас (или стороннюю библиотеку, такую ​​как OpenID), чтобы сделать это для вас, не является тривиальным обязательством.

При обзоре в 10 000 футов вы должны решить:

  • У вас есть имена пользователей, адреса электронной почты или идентификаторы пользователей в качестве основного селектора?
  • Как хранить пароли? PROTIP: password_hash() или scrypt - это путь.
  • Как вы должны обрабатывать флажки "помни меня"? В Интернете существует множество плохих стратегий для этого. Относитесь к каждому из них со скептицизмом, поскольку они могут создавать уязвимости в вашем приложении.
  • Как приложение должно обрабатывать пользователей, которые забыли свой пароль?

Информация в этом ответе актуальна и актуальна по состоянию на 9 мая 2015 г. и может быть устаревшей в связи с завершением конкурса по хешированию паролей

Первичные селекторы

Как правило, имена пользователей и адреса электронной почты лучше, чем идентификационные номера.

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

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

Хеширование пароля

Вам следует использовать password_hash() и password_verify(), если вы не обладаете достаточным опытом написания криптографических библиотек, чтобы идти дальше и выше.

За пределами Bcrypt

Иногда разработчикам нравится проявлять творческий подход (например, добавление «перца», что обычно означает предварительное хеширование или пароли HMAC со статическим ключом) и выходить за рамки стандартных реализаций. Мы сами сделали это, но очень консервативно.

Для наших внутренних проектов (которые имеют гораздо более высокий предел безопасности, чем блоги большинства людей), мы написали обертку вокруг этого API под названием PasswordLock, которая сначала хэширует пароль с sha256, затем base64 кодирует исходный хеш-код, затем передает этот хэш в кодировке base64 на password_hash() и, наконец, шифрует хеш bcrypt с помощью правильно реализованной библиотеки шифрования .

Повторим, вместо перечеркивания мы шифруем наши хэши паролей. Это дает нам большую гибкость в случае утечки (мы можем расшифровать, а затем повторно зашифровать, потому что мы знаем ключ). Кроме того, мы можем запустить наш веб-сервер и базу данных на отдельном оборудовании в одном центре обработки данных, чтобы уменьшить влияние уязвимости внедрения SQL. (Чтобы начать взламывать хэши, вам нужен ключ AES. Вы не можете получить его из базы данных, даже если сбежите в файловую систему.)

// Storage:
$stored = \ParagonIE\PasswordLock\PasswordLock::hashAndEncrypt($password, $aesKey);

// Verification:
if (\ParagonIE\PasswordLock\PasswordLock::decryptAndVerify($password, $stored, $aesKey)) {
    // Authenticated!
}

Хранение пароля с PasswordLock:

  1. hash('sha256', $password, true);
  2. base64_encode($step1);
  3. password_hash($step2, PASSWORD_DEFAULT);
  4. Crypto::encrypt($step3, $secretKey);

Подтверждение пароля с помощью PasswordLock:

  1. Crypto::decrypt($ciphertext, $secretKey);
  2. hash('sha256', $password, true);
  3. base64_encode($step2);
  4. password_verify($step3, $step1);

Дальнейшее чтение

11 голосов
/ 04 ноября 2009

Я использую OpenID .

Но, как и stackoverflow, я использую проект Google openid-selector для выполнения тяжелой работы.
Демо-страница здесь .

Очевидные преимущества (OpenID):

  • Вам не нужно быть экспертом по безопасности.
  • Пользователи доверяют крупным сайтам свою информацию.
  • Вы можете запросить такие вещи, как (псевдоним и т. Д.), Но пользователь должен выбрать.
  • Вам не нужно беспокоиться о:
    • процессы регистрации
    • забытый / забытый пароль
9 голосов
/ 09 ноября 2009

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

Отличный OpenID, или, если вы собираетесь запустить свою собственную, хотя бы используйте установленную библиотеку и следуйте документации!

8 голосов
/ 26 октября 2009

PHPass - это легкая библиотека хэширования паролей с переменной стоимостью, использующая bcrypt.

Переменная стоимость означает, что впоследствии вы можете увеличить «стоимость» хеширования паролей, чтобы плавно повысить безопасность без необходимости аннулировать ранее хешированные пароли пользователей.

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

5 голосов
/ 03 ноября 2009

Вход с использованием HTTP AUTH

  1. Использование Apache: http://httpd.apache.org/docs/2.2/howto/auth.html
  2. Это также возможно с IIS и другими веб-серверами .

После аутентификации для PHP вам просто нужно использовать $_SERVER['PHP_AUTH_USER'] для получения имени пользователя, использованного во время аутентификации.

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

Однако забудьте об интеграции вашей аутентификации в HTML-форму, если вы не реализуете полную схему HTTP AUTH из своего языка сценариев (как описано ниже).

Использование собственного HTTP AUTH на языке сценариев

Вы можете расширить Базовую аутентификацию HTTP , эмулировав ее на языке сценариев. Единственным требованием для этого является то, что ваш язык сценариев должен иметь возможность отправлять HTTP-заголовки HTTP-клиенту. Подробное объяснение того, как сделать это с помощью PHP, можно найти здесь: ( подробнее о PHP и HTTP AUTH ).

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

Недостатки HTTP AUTH

  1. Основным недостатком HTTP-аутентификации являются сложности, которые могут возникнуть при выходе из системы. Основной способ очистить сеанс пользователя - закрыть браузер или выдать заголовок с 403 Требуется аутентификация. К сожалению, это означает, что всплывающее окно HTTP AUTH возвращается на страницу и затем требует, чтобы пользователи либо снова вошли в систему, либо нажали «Отмена». Это может не сработать, если принять во внимание удобство использования, но можно обойти некоторые интересные результаты (т. Е. Использовать комбинацию файлов cookie и HTTP AUTH для сохранения состояния).

  2. HTTP AUTH всплывающие окна, сеанс и обработка заголовка HTTP определяются реализацией браузера в стандарте. Это означает, что вы застрянете с этой реализацией (включая любые ошибки) без возможности обхода проблемы (в отличие от других альтернатив).

  3. Базовый auth также означает, что auth_user и пароль отображаются в журналах сервера, а затем вам нужно использовать https для всего, так как в противном случае имя пользователя и пароль также передаются по сети при каждом запросе в виде простого текста.

4 голосов
/ 10 ноября 2009

Важно отделить уровень безопасности вашего приложения от остального. Если между вашей логикой приложения и системой связи нет расстояния, вы можете небезопасно общаться в одном месте и безопасно в другом месте. Возможно, вы допустите ошибку и отправите пароль в незашифрованном файле cookie, или, возможно, вы забудете проверить учетные данные пользователя за один шаг. Без «правильного» способа общения с пользователем вы наверняка совершите ошибку.

Например, допустим, теперь вы проверяете пользователей:

user_cookie = getSecureCookie()
if (user_cookie.password == session_user.password) {
    do_secure_thing()
    ...
}

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

if (userVerified()) {
    do_secure_thing()
    ...
}

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

1 голос
/ 07 марта 2013

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

Защищен паролем и прост в использовании с высокой надежностью и безопасностью. Есть несколько доступных за пределами EMC / RSA. Я предпочитаю PINSafe SwivelSecure.

Игорь С

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