Какой лучший способ создать систему входа с PHP [закрыт]


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

, Какой лучший способ - безопасный и простой - сделать систему логин и пароль?

Author: Tiago S, 2014-01-31

6 answers

Для безопасной аутентификации необходимо определить несколько моментов.

Некоторые элементы, которые должны заботиться:

  • SQL-Инъекция
  • Шифрования паролей
  • Атака грубой силы
  • Атак XSS
  • Атак CSRF
  • Защитить файлы сессии
  • Защитить файлы систем

1 - Начиная

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

define( 'SECURITY_HASH', 'uma frase qualquer ou letras aleatórias com números e simbolos' )

2 - Создайте таблицу в базе данных

, Предположение, таблицы

id
email
username
password
keymaster
last_ip
last_access
active
created_at
uptaded_at

3 - регистрация пользователя

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

Для проверки электронной почты используйте

if ( filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
    echo "This ($email_a) email address is considered valid.";
}

Пример того, как генерировать Хэш

crypt( rand(99999) . time() .  $_SERVER["REMOTE_ADDR"], SECURITY_HASH );

Более безопасный способ использовать данное назначение-это использовать какие - $2a$ в начале второго параметра, чтобы определить тип шифрования, который должен использоваться. Получаю следующим образом:

crypt( rand(99999) . time() .  $_SERVER["REMOTE_ADDR"], '$2a$07$' . SECURITY_HASH );

, Где $2a$ задает алгоритм шифрования Blowfish 07$ стоимость, чтобы генерировать хэш.

Или, если вы используете php 5.5 вы можете использовать функцию password_hash(). Узнайте больше в http://br1.php.net/manual/en/function.password-hash.php

$_SERVER["REMOTE_ADDR"] // Obtem o IP do usuário

Храните IP-адреса пользователя, даты последнего бесплатный, и, когда он был создан.

, Оставьте пользователь неработающий поля (active = 0 ) и проверка электронной почты зарегистрирован отправив электронное письмо с подтверждением.

В подтверждение по электронной почте вы сообщаете ссылку типа

http://www.dominio.com.br/validateuser.php?key={hash do resultado da concatenação do keymaster e SECURITY_HASH}

Этот url-адрес будет меняться поле active от 0 до 1, указывающее, что пользователь активирован.

4 - Войти

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

Искать информацию пользователей в базе, используя только имя пользователя в курсе.

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

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

5 - основной Уход

, Чтобы получить данные, переданные через POST или GET, избегайте использования глобальные переменные чисто. Используйте для этого filter_input().

Читайте в документации: http://www.php.net/manual/en/function.filter-input.php

--

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

Обновите хэш-всегда, что для отображения формы.

В Этой ссылке есть пример того, о профилактике данного вида атаки https://www.owasp.org/index.php/PHP_CSRF_Guard

--

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

  • Используйте PDO проверка всех переменные, прежде чем передать их в SQL.

  • установите в php.ini следующее session.cookie_httponly = 1 . Это говорит браузеру не подвергать файлы cookie, чтобы языки clients side, такие как javascript.
  • Назовите все файлы с расширением .php никогда с расширением, как .inc, .конференции, etc.
  • Избегайте использования md5 шифрование, используйте bcrypt поскольку алгоритм является гораздо более безопасным.
  • Сохранение сеанса в базе данных
  • Определите домена cookie
  • Подсчет попыток входа и время между ними, чтобы избежать роботами.
  • В производство, оставьте display_errors в значение off
  • , Управляет журнал ошибок и отправьте его электронной почты, это облегчает выявление попыток вторжения.
  • Осторожны с разрешениями файлов на сервере, убедитесь, что только apache и разрешение на них.

Некоторые ссылки полезный.

, Чтобы реализовать "запомнить меня" сделал краткое другой ответ здесь, на StackOverflow

 96
Author: marcusagm, 2017-04-13 12:59:44

, лучший подлинности подлинности

Ниже приведены некоторые рекомендации:

Переосмысление колесо

Если можно, используйте другие сайты для проверки подлинности. Есть технологии OpenId, что позволяет это, и это очень легко. Пример использования OpenId-это собственный веб-сайт stackoverflow: вы можете привязать свой пользователь stackoverflow с учетной записью Google или Facebook, например. Таким образом, вы делегирует безопасность вашего сайта на другие сайты, которые - теоретически - они более надежные. По крайней мере безопасностью для входа в систему доступа.

Никогда, никогда не храните пароли

Сохранить комбинацию пользователя / пароля является кошмаром для любого администратора и разработчика. Первый вариант (OpenId) является наиболее безопасным. Тем не менее, если OpenId-это не вариант, - допустим, есть сайт, который находится в Интрасети, который не имеет доступа к Интернету - как это сохранить имя пользователя и пароль. Таким образом, лучший подход заключается в сохранении пароль таким образом, что в случае возникновения какой-то кражи базы данных (таблицы пользователей и пароли), вы оцените работу для хакера, пришло время искать пароль. Это означает, что...

Никогда не храните пароли в виде простого текста

Первый подход, который все делает (я уже сделал... в 2002 году!), хранить пароли в виде простого текста. Пройдите тест: зарегистрироваться на любом веб-сайте и выберите пункт "Забыл пароль". Что должно произойти? Сайт будет отправлять сообщение о том, что вы в конкретный URL-адрес, введите новый пароль, и этот запрос истекает через x минут или в y часов. Что должно произойти, ни в коем случае, это сайт, отправить по электронной почте, чтобы вы с помощью пароля, который вы забыли. Если это произошло, поместите этот сайт в черный список, так как сохраняет пароли в виде простого текста. С другой стороны...

, Если будет использовать хэш, хорошо подумайте

Сначала это был план текста. Теперь вы узнали, и хотите, чтобы "развиваться". Что делает? Конечно, использует алгоритм генерации хэш-код, чтобы скрыть пароль. В принципе, алгоритм хэш-кода берет последовательность байтов, делает счет отлично сумасшедшая участием somatórias и или's-уникальные изгибы и retorce и генерирует код: хэш-код, относящийся к серии байтов, который был использован в качестве ввода. Это практически невозможно сделать вывод, пароль, просто смотрю, чтобы хэш-код генерируется. Это обычная одной рукой, скажем так. "Отлично! Я буду использовать хэш, и мне хорошо!" Быть... и не только. Давайте предположим, что вы выбрали алгоритм MD5 для создания хэш-кода. Парень, вы будете иметь две проблемы:

  1. Если парень вас есть компьютер, неприятный запах и немного времени, он может "взломать хэш". Как же так? Давайте предположим, что пароль, введенный дали хэш-код - aaaaabbcc0011 (это только пример, хэш-код MD5, имеет 32 шестнадцатеричных цифр). Хакер использует, то алгоритм грубой силы, который будет генерации паролей, пока один из них, дайте же хэш-код, что хэш-код, оригинальный пароль. Деталь: сгенерированный пароль, хакер может быть совершенно другой оригинальный пароль. Это явление называется столкновение, и в случае, если MD5 происходит с легкостью;

  2. Но хакер на самом деле знает, что пользователи не набирают пароли, то, что он делает? Он использует "каталог пароли". Хотите пример? В наиболее распространенных паролей на различных сайтах, это пресловутой последовательности 12345678. Хакер получает свою таблицу пользователей и пароли, и обратите внимание, что некоторые из них выглядят так: 25d55ad283aa400af464c76d713c07ad. Он не думает, два раз: вводите пароль 12345678 и счастлив. В Интернете есть множество каталогов с хэш-код, пароли из наиболее распространенных. Из-за этого...

Бросьте немного соли дал ей нравится

Способ еще более усложнить работу злоумышленника, это положить соль в генерации хэша. "Как же так?". Это просто: вы создаете код, буквенно-цифровой случайных любой, и время, чтобы генерировать хэш-код, вводите этот код и, желательно, генерирует новый хэш-код. Давайте вернемся к примеру 12345678. Давайте представим, что я был создан соли так же, случайных 1adef56ghdfr43256yb. Когда я генерировать код MD5 12345678, мы будем иметь то наш известный там сверху. Там я поймал наш известный, вместе с солью e... геро MD5 новый! Посмотрите результат: 7fb7daece2240e3ab134d6d4f9fe29fd. И если я сделаю это еще раз, я получаю: 1d2e962f721cee69fb3bca0d5ce9394b. Я могу сделать это столько раз, сколько хотите, при условии, что я повторить процедуру в момент, когда пользователь пытается выполнить проверку подлинности на веб-сайте. Несколько важных замечаний:

  1. В соль должна быть разной для каждого пользователя. Если же соль для каждого пользователя, сгенерированный код будет такой же, и там просто хакер найдет мане с паролем 12345678, что он (или она) думает слишком много;

  2. Соль нужно быть сохранен в базе данных. Ничто не мешает быть в разных таблицах, при условии, что не ухудшить производительность;

  3. Каждый раз, когда пользователь изменяет пароль, измените соль. Это гарантия больше;

Безопасность зависит от пароля, и идет за ней

Хорошо, даже с солью лучше не злоупотреблять, чтобы избежать зла соль, можно, например, использовать другие алгоритмы хеширования, такие как SHA1 или SHA2 в сочетании с солью. Существует также возможность шифрования пароля прямо в базе данных, но это, как правило, не является вариантом (в основном, на узлах общие). Так что, то, как это сохранить пароль, и сохранить его в базе, здесь будут конечными точками. Если вы сделаете это, вероятность что-то будет снижаться достаточно и ваш сайт будет более безопасной за вход:

Отключить register_globals, ради Бога!

Register_globals в PHP-это ридсам, tinhoso. Просто так. Как это работает? Давайте предположим, что ваша форма имеет поле с именем... имя (к сожалению, мое творчество только что там). С register_globals отключен, чтобы прочитать содержимое этого поля формы, вы используете $_GET['nome'] $_POST['nome']. Теперь, если register_globals установлена on, мотор PHP "волшебным образом" будет создать переменную с именем... $имя! Вы можете сделать вещи очень худых, на сайтах с register_globals включен. По умолчанию в PHP 5 это офф, но имеет sysop, который должен восстановить его за счет сайтов manés, которые все еще используют эту функцию. Если ваш sysop настроении, он позволит вам настроить register_globals вашего приложения в файле .htaccess находится в корневой каталог вашего сайта (это бежит немного рамки stackoverflow, но найдите в группы сайтов stackexchange, что вы думаете).

Сцепления SQL с параметрами: ваш друг хакер благодарит

, Если для выполнения запросов в бд всегда использовать методы и процедуры, которые поддерживают параметры связаны (bound parameters). Если вы являетесь PDO (рекомендую), будет что-то более или менее так:

$banco = new PDO(...);
$comando = $banco->prepare("SELECT ID, NOME FROM USUARIOS WHERE LOGIN = :login AND SENHA = :senha");

// Vamos considerar que você já pegou o sal daquele usuário e já aplicou os esquemas.
// Dá para fazer dentro do banco, se você preferir. É até melhor...

$comando->execute(array(':login' => $login, ':senha' => $senha_com_sal));

if ($comando->fetch()) { // Usuário logado!

} else { // Usuário incorreto ou a senha está incorreta!

}

, Почему этот подход лучше, чем просто объединить пароля, а также за кавычки? Для хакера, объединение позволяет тип атаки называется "SQL Инъекция". Обычно он делает так, что он ставит некоторые символы внутри одного из полей (имя, например), и там он может превратить невинную SELECT, который должен вывести 0 или 1 линии, на мощной SELECT, которая приносит все строки из таблицы. В зависимости от опыта хакер (и от неопытности разработчика), он может даже использовать insert'ы и update'ы и взорвать сайте, или открыть его полностью. Поиск SQL Injection attacks в Интернете и готовьтесь к сцены ужаса!

Примечание: эта система bound parameters также работает с mysqli и тому подобное. Поиск в документации. Стоит ооочень стоит.

Технология не побеждает хорошая социальная инженерия

Как я уже сказал ранее, много людей (много), или же использует в качестве паролей 12345678, superman, etc. для самых различных целей. Лучший способ избежать нападения (или оставить их еще более трудно), это заставить пользователя ввести пароли с минимальной безопасности. Установить правила создания паролей пользователей. Несколько простых правил, но что они могут сделать все различие: 1. Пароль должен иметь как минимум 8 символов; 2. Пароль должен иметь, по крайней мере, 2 буквы (a-z); 3. Пароль должен иметь, по крайней мере, 2 цифры (0-9); 4. Пароль должен иметь, по крайней мере, 2 буквы верхнего регистра (A-Z); 5. Пароль должен иметь, по крайней мере, 1 специальный символ, например,$&@#!% коммуникации.

И так далее.

Многие из этих советы я взяла из моего опыта, а также из этого видео (на английском языке): http://youtu.be/8ZtInClXe1Q

, удачи, и расскажите нам, как было.

 45
Author: Robson França, 2014-02-06 02:25:14

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

Необходимые Материалы

, Как мы будем с помощью набора классов PHP, myqli_* чтобы получить доступ к нашей базе данных mySQL, вам нужно из следующих версий PHP и mySQL: PHP версии 5 или выше MySQL версии 4.1.3 или выше Чтобы проверить версию PHP и mySQL на вашем сервере, с помощью функции phpinfo();.

Настройте Свой Сервер

Установите PHP и MySQL на вашем сервере. Большинство хостингов овладеют php и mySQL уже установлен, поэтому вам просто нужно убедиться, что они находятся с текущих версий каждого, что это руководство будет работать.

Настройка Базы Данных MySQL

1 Создание базы данных MySQL. В этом руководстве, вы научитесь создавать базы данных, называется "secure_login" (безопасный вход в систему). Это можно сделать через Phpmyadmin или с помощью команды SQL, чтобы создать его для вас.

Код для создания базы данных:

CREATE DATABASE `secure_login`;

Примечание: Некоторые узлы не позволяют создавать базы данных с помощью phpMyAdmin, и в случаях, где необходимо использовать cPanel.

2 Создайте пользователя с правами только SELECT (выбор), UPDATE (обновление) и INSERT (вставка).

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

  • Пользователь: "sec_user"
  • Пароль: "eKcGZr59zAa2BEWU"

Код для создания пользователь:

CREATE USER 'sec_user'@'localhost' IDENTIFIED BY 'eKcGZr59zAa2BEWU';
GRANT SELECT, INSERT, UPDATE ON `secure_login`.* TO 'sec_user'@'localhost';

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

3 Создайте таблицу MySQL с именем "members" ("членов").

Следующий код создает таблицы с 5 полями (id, username, email, password, salt).

Создайте таблицу "members:

CREATE TABLE `secure_login`.`members` (
  `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
  `username` VARCHAR(30) NOT NULL, 
  `email` VARCHAR(50) NOT NULL, 
  `password` CHAR(128) NOT NULL, 
  `salt` CHAR(128) NOT NULL
) ENGINE = InnoDB;

Мы используем тип данных CHAR для полей, которые мы знаем, размер (количество символов), таких как поля пароль (password) и "солт", который всегда будет иметь длину 128 символов. С помощью CHAR, здесь, вы будете экономить обработки.

4 Создайте таблицу для хранения попыток входа.

Использовать эту таблицу, чтобы хранить попытки логин пользователя. Таким образом, impediremos попытки атаковать с помощью грубой силы или грубой силы.

Создайте таблицу "login_attempts":

CREATE TABLE `secure_login`.`login_attempts` (
  `user_id` int(11) NOT NULL,
  `time` VARCHAR(30) NOT NULL 
) ENGINE=InnoDB

5 Создание тестовой линии в таблице "members".

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

  • Пользователя: test_user
  • Почты: [email protected]
  • Пароль: 6ZaxN2Vzm9NUJT2y

Добавить тестового пользователя:

INSERT INTO `secure_login`.`members` VALUES(1, 'test_user', '[email protected]', '00807432eae173f652f2064bdca1b61b290b52d40e429a7d295d76a71084aa96c0233b82f1feac45529e0726559645acaed6f3ae58a286b9f075916ebf66cacc', 'f9aab579fc1b41ed0c44fe4ecdbfcdb4cb99b9023abb241a6db833288f4eea3c02f76e0d35204a8695077dcf81932aa59006423976224be0390395bae152d4ef');

Создайте Страницу Подключения к Базе Данных

1 Создайте страницу подключения к базе данных.

Это код php, который будет использоваться для подключения к базе данных MySQL. Создайте новый php файл с именем "db_connect.php" и добавьте следующий код. Вы можете, а затем включить файл в любом страницы, которые вы хотите подключить к базе данных.

Соединение с базой данных (db_connect.php):

define("HOST", "localhost"); // O host no qual você deseja se conectar.
define("USER", "sec_user"); // O nome de usuário do banco de dados.
define("PASSWORD", "eKcGZr59zAa2BEWU"); // A senha do usuário do banco de dados. 
define("DATABASE", "secure_login"); // O nome do banco de dados.

$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);
// Se você estiver se conectando via TCP/IP ao invés de um socket UNIX, lembre-se de adicionar o número da porta como um parâmetro.

Создание Функций PHP

Эти функции будут делать все обработки сценария входа в систему. Добавьте все функции на одной странице " вызов "functions.php".

1 Войдите в PHP безопасной.

, важно не только поставить "session_start ()";, в верхней части всех страниц, на которых вы хотите использовать сеансы php, если вы действительно беспокоитесь о безопасности, этот путь, который вы должны сделать. Вы создаете функцию с именем "sec_session_start", в котором будет начать сеанс php и безопасно. Вы должны вызвать эту функцию в верхней части каждой страницы, из которой вы хотите получить доступ к переменной сеанса php.

Функция входа в Систему " Безопасный:

function sec_session_start() {
        $session_name = 'sec_session_id'; // Define um nome padrão de sessão
        $secure = false; // Defina como true (verdadeiro) caso esteja utilizando https.
        $httponly = true; // Isto impede que o javascript seja capaz de acessar a id de sessão. 

        ini_set('session.use_only_cookies', 1); // Força as sessões a apenas utilizarem cookies. 
        $cookieParams = session_get_cookie_params(); // Recebe os parâmetros atuais dos cookies.
        session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $secure, $httponly); 
        session_name($session_name); // Define o nome da sessão como sendo o acima definido.
        session_start(); // Inicia a sessão php.
        session_regenerate_id(true); // regenerada a sessão, deleta a outra.
}

Эта функция делает ваш сценарий входа в систему гораздо более безопасным. Предотвращает хакеры могли получить доступ к файл cookie идентификатора сеанса с помощью javascript (например, в атаке XSS). Также используется функция "session_regenerate_id()", которая заново создает идентификатор сеанса при каждом обновлении страницы, помогая предотвратить атаки hijack в систему. Примечание: Если вы используете https в своем приложении для входа, установите значение переменной "$secure" на "true".

2 Создайте функцию входа в систему.

Эта функция будет проверить адрес электронной почты и пароль в базе данных и возвращает значение "true" (истина), если оба являются корректными и объединения.

Функция Безопасного Входа в систему:

function login($email, $password, $mysqli) {
   // utilizar declarações preparadas significa que a injeção de código SQL não será possível. 
   if ($stmt = $mysqli->prepare("SELECT id, username, password, salt FROM members WHERE email = ? LIMIT 1")) { 
      $stmt->bind_param('s', $email); // Vincula "$email" ao parâmetro.
      $stmt->execute(); // Executa a query preparada.
      $stmt->store_result();
      $stmt->bind_result($user_id, $username, $db_password, $salt); // obtém variáveis do resultado.
      $stmt->fetch();
      $password = hash('sha512', $password.$salt); // confere o hash de "$password" e "$salt"
      if($stmt->num_rows == 1) { // se o usuário existe
         // Nós checamos se a conta está bloqueada devido a várias tentativas de login
         if(checkbrute($user_id, $mysqli) == true) { 
            // Conta está bloqueada
            // Envia um email ao usuário comunicando que sua conta foi bloqueada
            return false;
         } else {
         if($db_password == $password) { // Checa se a senha na base de dados confere com a senha que o usuário digitou. 
            // Senha está correta!

               $ip_address = $_SERVER['REMOTE_ADDR']; // Pega o endereço IP do usuário. 
               $user_browser = $_SERVER['HTTP_USER_AGENT']; // Pega a string de agente do usuário.

               $user_id = preg_replace("/[^0-9]+/", "", $user_id); // Proteção XSS conforme poderíamos imprimir este valor
               $_SESSION['user_id'] = $user_id; 
               $username = preg_replace("/[^a-zA-Z0-9_\-]+/", "", $username); // Proteção XSS conforme poderíamos imprimir este valor
               $_SESSION['username'] = $username;
               $_SESSION['login_string'] = hash('sha512', $password.$ip_address.$user_browser);
               // Login com sucesso.
               return true;    
         } else {
            // Senha não está correta
            // Nós armazenamos esta tentativa na base de dados
            $now = time();
            $mysqli->query("INSERT INTO login_attempts (user_id, time) VALUES ('$user_id', '$now')");
            return false;
         }
      }
      } else {
         // Nenhum usuário existe. 
         return false;
      }
   }
}

3 Функция Brute Force.

Атак грубой силы или грубой силы происходят, когда хакеры пытаются тысяч различных паролей для одной учетной записи, будь то форма randômica через случайные пароли или через словаре слов. В наш сценарий, если пользователь не в его попытке входа более 5 раз, его учетная запись будет заблокирована.

Функция login_check:

function checkbrute($user_id, $mysqli) {
   // Retorna a data atual
   $now = time();
   // Todas as tentativas de login são contadas pelas 2 últimas horas. 
   $valid_attempts = $now - (2 * 60 * 60); 

   if ($stmt = $mysqli->prepare("SELECT time FROM login_attempts WHERE user_id = ? AND time > '$valid_attempts'")) { 
      $stmt->bind_param('i', $user_id); 
      // Executa a query preparada.
      $stmt->execute();
      $stmt->store_result();
      // Se houver mais de 5 tentativas falhas de login
      if($stmt->num_rows > 5) {
         return true;
      } else {
         return false;
      }
   }
}

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

Столкнувшись с этой проблемой, большинство разработчики просто блокируют IP-адреса, после определенного количества логинов]. Различные инструменты для автоматизации процесса, эти инструменты могут пройти через серию прокси-серверов и даже изменить свой IP на каждый запрос. Заблокировать все эти ip-адреса может означать, что вы блокируете также IPs законных пользователей.

4 Чек статуса.

Это делается проверка, если переменные сеанса "user_id" и "login_string". Переменная сеанса "login_string" имеет IP-адрес и браузер в хешированном виде, а также пароль. Мы используем IP-адрес, информация из браузера, так как очень маловероятно, что пользователь, чтобы изменить IP-адрес компьютера или браузера во время сеанса. Делая это, вы не предотвращает атаки угон сессии (начала сеанса, в буквальном смысле).

Функция login_check:

function login_check($mysqli) {
   // Verifica se todas as variáveis das sessões foram definidas
   if(isset($_SESSION['user_id'], $_SESSION['username'], $_SESSION['login_string'])) {
     $user_id = $_SESSION['user_id'];
     $login_string = $_SESSION['login_string'];
     $username = $_SESSION['username'];
     $ip_address = $_SERVER['REMOTE_ADDR']; // Pega o endereço IP do usuário 
     $user_browser = $_SERVER['HTTP_USER_AGENT']; // Pega a string do usuário.

     if ($stmt = $mysqli->prepare("SELECT password FROM members WHERE id = ? LIMIT 1")) { 
        $stmt->bind_param('i', $user_id); // Atribui "$user_id" ao parâmetro
        $stmt->execute(); // Executa a tarefa atribuía
        $stmt->store_result();

        if($stmt->num_rows == 1) { // Caso o usuário exista
           $stmt->bind_result($password); // pega variáveis a partir do resultado
           $stmt->fetch();
           $login_check = hash('sha512', $password.$ip_address.$user_browser);
           if($login_check == $login_string) {
              // Logado!!!
              return true;
           } else {
              // Não foi logado
              return false;
           }
        } else {
            // Não foi logado
            return false;
        }
     } else {
        // Não foi logado
        return false;
     }
   } else {
     // Não foi logado
     return false;
   }
}

Создание Страниц Обработки

1 *Создайте страницу обработки логин (process_login.php).*

Следуя нашему предыдущему примеру, это нужно назвать process_login.php. Мы будем использовать набор для PHP функции mysqli_* за расширение текущей версии mysql.

Страницу обработки входа в систему (process_login.php)

include 'db_connect.php';
include 'functions.php';
sec_session_start(); // Nossa segurança personalizada para iniciar uma sessão php. 

if(isset($_POST['email'], $_POST['p'])) { 
   $email = $_POST['email'];
   $password = $_POST['p']; // A senha em hash.
   if(login($email, $password, $mysqli) == true) {
      // Login com sucesso
      echo 'Sucesso: Você efetuou login.';
   } else {
      // Falha de login
      header('Lozalização: ./login.php?error=1');
   }
} else { 
   // As variáveis POST corretas não foram enviadas para esta página.
   echo 'Requisição Inválida';
}

2 Создайте сценарий выхода из системы.

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

Сценария Выхода из системы (logout.php):

include 'functions.php';
sec_session_start();
// Zera todos os valores da sessão
$_SESSION = array();
// Pega os parâmetros da sessão 
$params = session_get_cookie_params();
// Deleta o cookie atual.
setcookie(session_name(), '', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"]);
// Destrói a sessão
session_destroy();
header('Lozalização: ./');

, обратите Внимание: Может быть хорошей идеей, чтобы добавить защиту CSFR здесь на случай, если кто-нибудь отправить ссылку с этой страницы каким-то образом. Пользователь будет deslogado.

3 Страница регистрации.

, Чтобы создать хэш пароля, вам необходимо использовать следующий код:

Сценария Хеш:

// A senha em hash do formulário
$password = $_POST['p']; 
// Cria um salt randômico
$random_salt = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
// Cria uma senha pós hash (Cuidado para não re-escrever)
$password = hash('sha512', $password.$random_salt);

// Adicione sua inserção ao script de base de dados aqui 
// Certifique-se de utilizar declarações preparadas
if ($insert_stmt = $mysqli->prepare("INSERT INTO members (username, email, password, salt) VALUES (?, ?, ?, ?)")) {    
   $insert_stmt->bind_param('ssss', $username, $email, $password, $random_salt); 
   // Execute a query preparada.
   $insert_stmt->execute();
}

Убедитесь, что значение $_POST['p'] уже в хэш-значение из javascript. Если вы не используете этот метод, необходимо проверить пароль на стороне сервера, убедитесь, что вы используете хэш.

Создайте JavaScript-Файлов

1 Создайте файл sha512.js.

Данный файл является реализация в javascript алгоритма хэширования, sha512. Мы будем использовать функцию хеширования, чтобы наши пароли не передаются в текст pĺano. Файл может быть загружен с http://pajhome.org.uk/crypt/md5/sha512.html

2 Создайте файл forms.js.

Этот файл будет обрабатывать хэш паролей для любой формы.

Файл JavaScript Форме (forms.js):

function formhash(form, password) {
   // Cria um novo elemento de entrada, como um campo de entrada de senha sem hash.
   var p = document.createElement("input");
   // Adiciona o novo elemento ao nosso formulário.
   form.appendChild(p);
   p.name = "p";
   p.type = "hidden"
   p.value = hex_sha512(password.value);
   // Certifica que senhas em texto plano não sejam enviadas.
   password.value = "";
   // Finalmente, submete o formulário.
   form.submit();
}

Создание HTML-Страниц

1 Создайте форму для входа (логин.php).

Это HTML-форма с двумя текстовыми полями, так называемый "почты" и "password". JavaScript будет затем создать хэш пароля и отправить "по электронной почте" и "p" (хэш-код, пароль) на сервер.

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

Регистрационную Форму HTML:

<script type="text/javascript" src="sha512.js"></script>
<script type="text/javascript" src="forms.js"></script>
<?php
if(isset($_GET['error'])) { 
   echo 'Erro ao Logar!';
}
?>
<form action="process_login.php" method="post" name="login_form">
   Email: <input type="text" name="email" /><br />
   Password: <input type="password" name="password" id="password"/><br />
   <input type="button" value="Login" onclick="formhash(this.form, this.form.password);" />
</form>

Примечание: Даже если у нас есть зашифрованный пароль, что это не будет отправлено в виде простого текста, рекомендуется, что вы используете протокол https (TLS/SSL), когда вы отправляете пароли.

Защита Страницы

1 Сценарий Защиты Страниц.

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

// Inclua a conexão com a base de dados e as funções aqui.
sec_session_start();
if(login_check($mysqli) == true) {

   // Adicione o conteúdo de sua página protegida aqui.

} else {
   echo 'Você não está autorizado a acessar esta página. Por favor, efetue login. <br/>';
}

КОНЕЦ ;)

Источник: http://www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL

 20
Author: Walter Gandarella, 2014-02-06 00:50:35

Вопрос: Какой лучший способ сделать систему входа в пароль с помощью PHP?

Ответ: " Не существует "лучший способ". Есть несколько решений, качество, каждый из которых является лучшим в определенном контексте.

 10
Author: J. Bruni, 2014-02-05 20:43:51

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

Мой ответ предполагает, что ваш интерес будет в том, чтобы создать систему, которая в какой-то момент перейдет в производство; если интерес есть-образовательного вы можете использовать алгоритм хэширования, простые и сохранить комбинации имени и пароля в локальной базе данных, а затем искать глубже темы, такие как хэширование, salting, etc.

 9
Author: Rodrigo Deodoro, 2014-01-31 17:07:05

В PHP используйте Argon2id, доступно в PHP 7.2:

$hash_str = sodium_crypto_pwhash_str($password, 
       SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
       SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);

Используйте sodium_crypto_pwhash_str_verify($hash_str, $password).

Вы также можете использовать Argon2i:

$hash_str = password_hash($password , PASSWORD_ARGON2I, [
          'memory_cost' => PASSWORD_ARGON2_DEFAULT_MEMORY_COST, 
          'time_cost' => PASSWORD_ARGON2_DEFAULT_TIME_COST, 
          'threads' => PASSWORD_ARGON2_DEFAULT_THREADS
]);

Используйте password_​verify($password, $hash_str).

Если версия PHP устарела, поэтому безопасность не кажется, быть вашим приоритетом. Если вы все еще используете версию "поддерживается", но не имеет Argon2, используйте BCrypt: password_hash($password , PASSWORD_BCRYPT, ['cost' => 13]);. Если не BCrypt доступен, то используйте PBKDF2.

Несколько ответы есть серьезные проблемы!

  1. Использовать rand(), mt_rand() или - uniqid() и до time()...

    Все эти хороши для создания уникальных, до определенного момента. Spotify использует mt_rand(), чтобы выбрать в случайном порядке, из песни, для этой цели он хорош, это быстро. Игра может использовать его для создания эффектов дыма, ок. Теперь, для паролей, он не должен быть только один. Он должен быть уникальным, impressível (нападающий) и до сих пор есть распределение результатов. Вскоре злоумышленник не может предсказать следующее значение, и получить значения, созданные ранее. В зависимости от генератора, даже не нападая на пуле энтропии, употреблять, чтобы re-seed, вы сможете узнать, байты, созданные, что не знает его текущее состояние.

    mt_rand() повторит все значения в том же порядке после X числа генерируются. Кроме того, с образцом ~700 номеров, порожденных вы можете предсказать, все рядом.

    Жемчужина максимальная использовать time(), посмотрите на ваши часы и вы знаете цену, на самом деле он является уникальным (он unixtime), но, очевидно, предсказуемо. На самом деле, он не единственный, атаковать NTP-сервер, который вы, вероятно, использует для синхронизации даты и времени, вы вернетесь во времени.

    Используйте random_bytes, или просто прочитайте /dev/urandom, если таковые имеются. Эти два CSPRNG и должны быть использованы для этих целей.

  2. Использовать SHA-2, SHA-1, MD5, SHA-3....

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

    Лучшие решения, которые у вас есть BCrypt и Argon2i, оба доступны на PHP 7.2. В то время как BCrypt и PBKDF2 доступны, начиная с PHP 5.5. Все эти деривации ключей (KDF), или также называют Пароль Хеширования, это отличается от хеш-значения общего пользования, такие как SHA-2.

    Argon2i сложность, которая является настраиваемой. Это предполагает более широкое использование памяти, использование обработки параллельно и по-прежнему количество раундов, итераций, необходимых для простой пароль. Чем больше трудность, тем больше будет времени, чтобы сделать хеширование одной строки. В BCrypt имеет ресурсы подобны, но не время можно увеличить индивидуально. Уже PBKDF2 имеет только количество итераций (что в основном N * HMAC(), очень грубо говоря), это худшее из лучших методов, которые можно использовать.

  3. Использование salt и, полагая, что это спасение.

    salt нет, это чудо. В нем НЕ ЗАДЕРЖИВАЕТ нападения перебор. Если у вас есть HASH(x) HASH(x + y) разницу во времени для вычисления оба чрезвычайно презренный, если y for нескольких байтов, он будет равен. Кроме того, если вы сделаете HASH(salt + senha) злоумышленник может обойти salt полностью, если он будет того же размера (или больше), что и блок хеш.

    salt было сделано только для двух пароли отличаются между собой, и только. Если у вас есть функция HASH(string, salt), а потом делает BCRYPT(x, y) BCRYPT(x, z) результат для x будет отличаться, потому что salts (y и z) отличаются. Это предотвращает, что злоумышленник перерыв несколько паролей в то же время, просто.

    Стоимость от brute-force является гораздо более сложным, поставляется с использование памятью, параллелизм, возможность pre-вычислительных и даже несколько целей. Это то, что делается в использовании Argon2, BCrypt и даже разумно в PBKDF2. Эти функции не являются хорошими, потому что используют salt, salt делается для целей, различные повышения, чтобы увеличить сложность.

  4. Использовать == ===.

    Это уязвим к тайминги-attack. Это справедливо для всех языков, практически. Большинство языков использует memcmp() или аналогичные функции, что делает быстро, но не является безопасным.

    Но, не только, PHP имеет функцию, иметь динамическую типизацию, и это за несколько неожиданные последствия для некоторых из них. В общем, никогда не используйте ==, или вы можете увидеть что-то вроде sha1('aaroZmOk') == sha1('aaK1STfY') возвращение true. Это не столкновение SHA-1, это только потому, что они оба начинаются с 0e и == выполняет работу, конвертировать и затем стать действительным, то, что не возникает ===.

    PHP имеет hash_equals(), несмотря на название он может быть использован для любых целей, то есть hash_equals('a', 'a') работает. Несмотря на префикса hash_ strings, занимающихся не должна быть криптографических хэш.

 7
Author: Inkeliz, 2018-07-06 19:54:34