Аутентификация пользователя в PHP — Учебник по PHP — HTML Academy

Немного воды или, что же автор хотел всем этим сказать?

В преамбуле к статье я писал, что занимаюсь дурью проектирую протокол беспарольной аутентификации в Web, который бы сильно облегчил всем нам (конечным пользователям сайтов) жизнь, избавляя от парольного ада. И эта статья написана, чтобы  «раскрывать причины технических решений, закладываемых в новый протокол». Так вот, касаемо схемы авторизации, я делаю ставку на SRP.

На самом деле протоколов авторизации гораздо больше, чем было описано выше. Но SRP – это, на мой взгляд, самая крутая схема, созданная профильным специалистом, выпускником Стэндфордского университета (Thomas Wu), и проверенная его коллегами и другими специалистами по безопасности.

Возникает закономерный вопрос? Если эта схема такая крутая и древняя, почему она не получила до сих пор широкого распространения.

Я думаю, что этот протокол просто опередил свое время. Тогда аутентификацию предполагалось выполнять на клиенте в браузере. А javascript находился в зачаточном состоянии и мог, в лучшем случае вывести алертом «hello word». А нужна была арифметика на больших числах. Сейчас уже есть, но время упущено.

И самое главное, веб сообщество до сих пор не осознало, что процесс аутентификации необходимо выносить за рамки прямого взаимодействия сервер–браузер (равно как и аутентификацию в иных системах). В самом деле, ведь никто в здравом уме не хотел бы реализовывать вручную TLS  (на javascipt/PHP/JAVA)?

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

Что делать, если при вводе правильного пароля на айфоне появляется ошибка

Если такая ситуация возникла при вводе пароля на вашем айфоне (к примеру, при подключении к Wi-Fi), тогда выполните следующее:

  • Ещё раз посимвольно проверьте, что вы ввели пароль правильно;
  • Убедитесь, что вы выполняете подключение к нужной сети (сервису), и не перепутали пароли;
  • Проверьте, что вы используете правильный регистр, и не используете большие буквы вместо маленьких, и наоборот;
  • Убедитесь, что у вас включена правильная клавиатура (русская вместо украинской, английская вместо русской и др.), на которой набирается пароль;
Похожее:  Личный кабинет великом

Обычно используется английская раскладка

  • Перезагрузите ваш телефон. Нажмите и удерживайте кнопку питания до появления ползунка, затем перетяните ползунок для выключения телефона. После того, как экран станет чёрным, нажмите и удерживайте кнопку питания для включения девайса;
  • Забудьте точку доступа Wi-Fi. Если вы не можете подключиться к нужному вай-фай, забудьте в настройках сети данную точку доступа (Настройки – Wi-Fi – «Забыть эту сеть» — «Забыть»). Подождите пару секунд, затем вновь попытайтесь подключиться к сети;
  • Сбросьте настройки сети. Перейдите в « Настройки », затем тапните на « Основные », далее « Сброс », и потом « Сбросить настройки сети »;
  • Перезапустите роутер;
  • Попробуйте подключиться к другой сети с паролем;
  • Используйте опцию « Поделиться паролем » (для iOS11). Вам понадобятся два телефона – проблемный (не может войти в сеть) и другой. На проблемном телефоне забудьте точку вай-фай, а затем подключитесь, но не вводите пароль. Поднесите к проблемному телефону второе устройство (на котором пароль сохранён и работает нормально), и на втором телефоне появится предложение поделиться паролем. Далее система всё сделает в автоматическом режиме;
  • Сбросьте устройство до заводских настроек («Настройки» — «Основные» — «Сброс» — «Стереть контент и настройки»). Перед сбросом скопируйте на другой носитель важные файлы и данные.

Данные советы также актуальны для большинства планшетов, работающих на базе iOS.

Почему появляется уведомление «пароль неверный» при корректном вводе пароля на андроид

В случае моделей на базе ОС Андроид инструкция во многом похожа с советами для айфона. Советы можно применить для телефонов и таблетов на Андроид.

Выполните следующее, чтобы понять, почему выводится ошибка «Пароль неверный» при корректном вводе данных:

  • Ещё раз посимвольно проверьте, что вы ввели пароль правильно;
  • Убедитесь, что вы выполняете подключение к нужной сети (сервису), и не перепутали пароли;
  • Убедитесь, что вы используете правильный регистр, и не используете большие буквы вместо маленьких, и наоборот;
  • Убедитесь, что у вас включена правильная раскладка клавиатуры;
  • Перезагрузите ваш телефон. Нажмите и удерживайте кнопку питания вашего телефона, в появившемся меню выберите « Перезагрузить »;
  • Забудьте точку доступа Wi-Fi. Если вы не можете подключиться к нужному вай-фай, забудьте в настройках сети данную точку доступа. Перейдите в Настройки – Подключения — Wi-Fi, затем выберите вашу сеть и тапните на шестерёнку рядом с ней. На следующем экране выберите « Забыть ». Подождите пару секунд, затем вновь попытайтесь подключиться к сети;
  • Перезапустите ваш роутер;
  • Попробуйте подключиться к другой сети с паролем;
  • Сбросьте устройство до заводских настроек («Настройки» — «Общие настройки» — «Сброс»). До сброса сделайте бекап важных для вас данных.

Что такое хеширование

Отпечаток (хэш) — это результат работы функции хэширования, которая вернёт для любого значения строку фиксированной длины.Используя специальный математический алгоритм, такая функция умеет преобразовывать любую переданную информацию к строке фиксированной длины (например, 32 или 64 символа).

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

Возьмём простой пример. У нас есть информация, для которой мы хотим получить отпечаток. Пусть такой информацией будет следующая строка:

«Я знаю только то, что ничего не знаю, но другие не знают и этого»

Результат обработки этой строки хэширующей функцией SHA-1 будет таким:6b3cb0df50fe814dee886b4e1c747dda6ce88b37

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

Scrypt’им

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

Производительность компьютеров растет. И хотя закон Мура давно как не действует (по слухам, с 2006 года), и рост уже не экспоненциальный, на “плато” мы ещё не вышли. То что ранее считалось невозможным, теперь доступно многим. Например, аренда на время вычислительных кластеров с фантастической мощностью.

поговаривают, что

количество хешей, которое обсчитывается в сети Bitcoin каждые три секунды, достаточно, чтобы найти коллизию для SHA-1. Источник.

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

Как? В начале по таблице известных паролей: синтетических qwerty, популярных 123 и когда-то угнанных реальных. Затем, путём тупого перебора символов из заданного алфавита. Алгоритм концептуально прост: берем пароль-кандидат, вычисляем hash( password, salt ), сравниваем результат. Соль учетной записи известна, ибо хранится рядом с хешем пароля.

На нашу беду, процесс перебора хорошо параллелится. А значит, в теории рост производительности не ограничен (правда только в теории; практика – вещь куда более суровая).

Вот для примера расчеты

Этой проблемой озадачились уже достаточно давно. И в результате усилий криптографов, на свет появилась такая функция как scrypt.

Функция scrypt делает почти тоже самое, что и хэш-функция (на самом деле использует в качестве базы SHA2-256), но создана таким образом, чтобы усложнить атаку перебором при помощи ПЛИС: FPGA, ASIC и подобных. Она заставляет использовать в алгоритме много циклов и ветвлений (чего суперскаллярные процессоры крайне не любят), к тому же, требует слишком много памяти на одно ядро.

Поэтому, вместо стандартной хеширующей функции, мы будем использовать scrypt. WebCryptApi пока её не поддерживает, но для javascript-разработчиков есть уже реализованные библиотеки. В остальном схема взаимодействия пока остается прежней. И вроде бы, надежной.

Но защитит ли она от пассивного MitM? Нет. Ибо мы всё ещё посылаем на сервер всегда один и тот же хеш. А значит, перехватив передачу итогового хеша на сервер, злоумышленник может в последствии легально его использовать для входа под чужой учеткой.

Финальный штрих

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

Можно. И даже более того. Фактически мы можем сделать так, что угон аутентификационных данных пользователей будет бессмысленным. Компрометация этих сведений не принесет взломщику ничего (ну правда, он может «поживиться» куда более ценными сведениями; например данными сохраненных кредитных карт и cvc-кодами для них; но мы ведь защищаем процессы авторизации, а не проектируем PCI DSS).

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

КРАЙНЕ ВАЖНОЕ ЗАМЕЧАНИЕ: если вдруг кому-то покажется интересной какая-то из двух рассмотренных далее схем, ни в коем случае не спешите внедрять. Внимательно изучите сравнительную таблицу недостатков и уязвимостей. Опять же, не забывайте про опасность использования «учебных» криптопротоколов. Я предупредил.

А Схема защиты на симметричных ключах

Пусть H – это тот самый хеш клиента, по которому сервер его аутентифицирует. H хранится на сервере. H может быть потенциально стать доступным взломщику БД.

Пусть клиент имеет некий ключ K, которым он зашифровывает свой исходный аутентификационный хеш H: V = EK(H), где E – функция шифрования на ключе K. Итоговый шифр V вместе с H сервер хранит в своей БД. Если алгоритм шифра выбран надежный, то из пары (V, H) восстановить исходный ключ почти невозможно.

Теперь в процессе аутентификации нам остается передать защищенным образом пару (H, V) серверу. Тот сверит H, расшифрует V и убедится, что мы действительно знаем ключ К, а не украли H при взломе БД. 

Это был концепт. Теперь конкретика. 

Определим функцию hmac как функцию HMAC-SHA2-256. Salt и challenge должны быть равны длине блока хеширующей функции. В нашем случае – 256 бит. Определим функцию E – как функцию шифрования, а функцию D – как функцию расшифровывания на базе симметричного шифра AES-256.  Наконец, определим функцию scrypt, как функцию, возвращающую 256-битный хеш от пароля и его соли.

На стороне клиента производятся предварительные вычисления:

  1. Защитим исходный пароль пользователя, вычислив H_p=scrypt(password,salt).

  2. Сформируем аутентификационный хеш H=hmac_{H_p}(login).

  3. Сформируем код подтверждения .

  4. Сформируем шифр аутентификационного хеша V = E_K (H).

При регистрации клиент посылает серверу пару (H, V) в открытом виде. Заметим, что сервер не знает ни исходный пароль пользователя, ни его первичный хеш Hp.

Алгоритм авторизации клиента теперь такой:

Авторизация с помощью подключенного устройства

Авторизация с помощью подключенного устройства — это идентификация через Bluetooth (или нечто подобное), то есть присоединение одного устройства к другому, которое уже идентифицировало пользователя.

Например, для Mac OS X есть приложение KeyTouch, позволяющее авторизоваться на компьютере со сканом отпечатков пальцев со своего iPhone. Есть еще и Knock, который позволяет кликнуть по телефону, чтобы разблокировать компьютер.

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

Аутентификация пользователя в PHP — Учебник по PHP — HTML AcademyПриложение Tether для iPhone

В домашнем офисе я использую приложение Mac OS X и iOS под названием Tether («связка»). После однократной синхронизации компьютера и телефона компьютер блокируется и разблокируется — в зависимости от близости телефона к компьютеру.

Tether сэкономил мне массу времени. Набор моего пароля с заглавными буквами, цифрами и символами может занять всего три или четыре секунды, но много раз повторять это каждый день, неделю и месяц — это уже слишком. Благодаря идентификации подключенного устройства к тому времени, когда я сажусь в кресло, мой компьютер уже разблокирован. Еще один пример — ключи от машины с Bluetooth.

Безопасный метод авторизации на php

Примечание: мини-статья написана для новичков

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

1. Модель (клиент)
Регистрация
— логин (a-z0-9)
— пароль
Вход
— логин
— пароль
Cookie
— уникальный идентификатор юзера
— хэш

Модель (сервер)
MySQL
Таблица users
user_id (int(11))
user_login (Varchar(30))
user_password (varchar(32))
user_hash (varchar(32))
user_ip (int(10)) по умолчанию 0

При регистрации в базу данных записываеться логин пользователя и пароль(в двойном md5 шифровании)

При авторизация, сравниваеться логин и пароль, если они верны, то генерируеться случайная строка, которая хешируеться и добавляеться в БД в строку user_hash. Также записываеться IP адрес пользователя(но это у нас будет опциональным, так как кто-то сидит через Proxy, а у кого-то IP динамический… тут уже пользователь сам будет выбирать безопасность или удобство). В куки пользователя мы записываем его уникальный индетификатор и сгенерированный hash.

Почему надо хранить в куках хеш случайно сгенерированной строки, а не хеш пароля?
1. Из-за невнимательности программиста, во всей системе могут быть дырки, воспользовавшийсь этими дырками, злоумышленик может вытащить хеш пароля из БД и подставить его в свои куки, тем самым получить доступ к закрытым данным. В нашем же случае, двойной хеш пароля не чем не сможет помочь хакеру, так как расшифровать он его не сможет(теоретически это возможно, но на это он потратит не один месяц, а может быть и год) а воспользоваться этим хешем ему негде, ведь у нас при авторизации свой уникальный хеш прикрепленный к IP пользователя.

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

2. Практика
-- <br>
-- Структура таблицы `users` <br>
-- <br>
CREATE TABLE `users` ( <br>
`user_id` int(11) unsigned NOT NULL auto_increment, <br>
`user_login` varchar(30) NOT NULL, <br>
`user_password` varchar(32) NOT NULL, <br>
`user_hash` varchar(32) NOT NULL, <br>
`user_ip` int(10) unsigned NOT NULL default '0', <br>
PRIMARY KEY (`user_id`) <br>
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=1 ; <br>

register.php

<?

// Страница регситрации нового пользователя

# Соединямся с БД

mysql_connect(“localhost”“myhost”“myhost”);

mysql_select_db(“testtable”);

if(isset($_POST[‘submit’]))

{

    $err = array();

    # проверям логин

    if(!preg_match(“/^[a-zA-Z0-9] $/”,$_POST[‘login’]))

    {

        $err[] = “Логин может состоять только из букв английского алфавита и цифр”;

    }

    if(strlen($_POST[‘login’]) < or strlen($_POST[‘login’]) > 30)

    {

        $err[] = “Логин должен быть не меньше 3-х символов и не больше 30”;

    }

    # проверяем, не сущестует ли пользователя с таким именем

    $query mysql_query(“SELECT COUNT(user_id) FROM users WHERE user_login='”.mysql_real_escape_string($_POST[‘login’]).“‘”);

    if(mysql_result($query0) > 0)

    {

        $err[] = “Пользователь с таким логином уже существует в базе данных”;

    }

    # Если нет ошибок, то добавляем в БД нового пользователя

    if(count($err) == 0)

    {

        
$login $_POST[‘login’];

        # Убераем лишние пробелы и делаем двойное шифрование

        $password md5(md5(trim($_POST[‘password’])));

        mysql_query(“INSERT INTO users SET user_login='”.$login.“‘, user_password='”.$password.“‘”);

        header(“Location: login.php”); exit();

    }

    else

    {

        print “<b>При регистрации произошли следующие ошибки:</b><br>”;

        foreach($err AS $error)

        {

            print $error.“<br>”;

        }

    }

}

?>

<form method=”POST”>

Логин <input name=”login” type=”text”><br>

Пароль <input name=”password” type=”password”><br>

<input name=”submit” type=”submit” value=”Зарегистрироваться”>

</form>

login.php

<?

// Страница авторизации

# Функция для генерации случайной строки

function generateCode($length=6) {

    $chars “abcdefghijklmnopqrstuvwxyzABCDEFGHI JKLMNOPRQSTUVWXYZ0123456789”;

    $code “”;

    $clen strlen($chars) – 1;  
while (strlen($code) < $length) {

            $code .= $chars[mt_rand(0,$clen)];  
}

    return $code;

}

# Соединямся с БД

mysql_connect(“localhost”“myhost”“myhost”);

mysql_select_db(“testtable”);

if(isset($_POST[‘submit’]))

{

    # Вытаскиваем из БД запись, у которой логин равняеться введенному

    $query mysql_query(“SELECT user_id, user_password FROM users WHERE user_login='”.mysql_real_escape_string($_POST[‘login’]).“‘ LIMIT 1”);

    $data mysql_fetch_assoc($query);

    # Соавниваем пароли

    if($data[‘user_password’] === md5(md5($_POST[‘password’])))

    {

        # Генерируем случайное число и шифруем его

        $hash md5(generateCode(10));

        if(!@$_POST[‘not_attach_ip’])

        {

            # Если пользователя выбрал привязку к IP

            # Переводим IP в строку

            $insip “, user_ip=INET_ATON(‘”.$_SERVER[‘REMOTE_ADDR’].“‘)”;

        }

        # Записываем в БД новый хеш авторизации и IP

        mysql_query(“UPDATE users SET user_hash='”.$hash.“‘ “.$insip.” WHERE user_id='”.$data[‘user_id’].“‘”);

        # Ставим куки

        setcookie(“id”$data[‘user_id’], time() 60*60*24*30);

        setcookie(“hash”$hashtime() 60*60*24*30);

        # Переадресовываем браузер на страницу проверки нашего скрипта

        header(“Location: check.php”); exit();

    }

    else

    {

        print “Вы ввели неправильный логин/пароль”;

    }

}

?>

<form method=”POST”>

Логин <input name=”login” type=”text”><br>

Пароль <input name=”password” type=”password”><br>

Не прикреплять к IP(не безопасно) <input type=”checkbox” name=”not_attach_ip”><br>

<input name=”submit” type=”submit” value=”Войти”>

</form>

check.php

<?

// Скрипт проверки

# Соединямся с БД

mysql_connect(“localhost”“myhost”“myhost”);

mysql_select_db(“testtable”);

if (isset($_COOKIE[‘id’]) and isset($_COOKIE[‘hash’]))

{   

    $query mysql_query(“SELECT *,INET_NTOA(user_ip) FROM users WHERE user_id = ‘”.intval($_COOKIE[‘id’]).“‘ LIMIT 1”);

    $userdata mysql_fetch_assoc($query);

    if(($userdata[‘user_hash’] !== $_COOKIE[‘hash’]) or ($userdata[‘user_id’] !== $_COOKIE[‘id’])<br> or (($userdata[‘user_ip’] !== $_SERVER[‘REMOTE_ADDR’])  and ($userdata[‘user_ip’] !== “0”)))

    {

        setcookie(“id”“”time() – 3600*24*30*12“/”);

        setcookie(“hash”“”time() – 3600*24*30*12“/”);

        print “Хм, что-то не получилось”;

    }

    else

    {

        print “Привет, “.$userdata[‘user_login’].“. Всё работает!”;

    }

}

else

{

    print “Включите куки”;

}

?>

Для защиты формы логина от перебора, можно использовать <a href=«captcha.ru target=»_blank”>капчу.

Хочу отметить, что здесь я рассматривал авторизацию основоную на cookies, не стоит в комментариях кричать, что сессии лучше/удобнее и т.д. Спасибо.

Беспарольная авторизация

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

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

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

Аутентификация пользователя в PHP — Учебник по PHP — HTML AcademyАвторизация в Slack

У Slack есть очень хороший пример беспарольной идентификации. На разных этапах входа в систему и процессов сброса пароля сервис использует «волшебную ссылку» (magic link) для идентификации пользователей. Уникальный URL отправляется на электронный адрес пользователя, и этот URL открывает приложение и позволяет ему войти.


Примечательна сама презентация этой модели взаимодействия: она представляет контакт пользователя с системой как «магию», упрощая его и успокаивая пользователя (вероятно, придумавший «двухфакторную идентификацию» неправильно понял ее брендинг).

Биометрическая идентификация

Отпечатки пальцев, сканы сетчатки глаза, распознавание лица, голоса и многое другое — все это биометрическая авторизация.

Наиболее распространенный пример — Touch ID компании Apple. Такие вещи действительно восхищают. Биология — наша истинная идентичность, она всегда с нами. Мы знаем об идее разблокирования телефонов или планшетов при помощи отпечатка пальца. Тем не менее биометрическая идентификация используется и в других местах (и с другими параметрами).

Windows Hello — это перспективная система идентификации для Windows 10, соединяющая камеры с датчиками (на компьютерах и устройствах) для распознавания лица, радужки глаз или отпечатков пальцев. Нужно просто открыть компьютер и заниматься своими делами, не жертвуя при этом безопасностью. Этот тип идентификации был до недавнего времени невозможен, особенно в масштабе Windows 10.

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

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

Биометрическая идентификация только начинает развиваться, но некоторые API и библиотеки позволяют нам пользоваться биометрической идентификацией уже сегодня. К ним относятся BioID Web Service, KeyLemon, Authentify и Windows Biometric Framework API (на котором, как мне кажется, построена Hello).

Истоки проблемы


Все мы не очень любим авторизацию через пароль. Чем больше сервисов мы используем, тем больше паролей приходится запоминать.

Приложения SaaS, социальные сети и другие службы требуют соблюдать строгие правила введения паролей, которые затрудняют вход в систему для честных пользователей. Неужели авторизация вида «имя пользователя и пароль» настолько незаменима, что мы готовы смириться с этим препятствием при использовании сервисов и продуктов?

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


Для этого уже есть несколько методов и постоянно появляются новые. Традиционную аутентификацию при помощи пароля можно сделать комфортной и удобной. Вот актуальные способы:

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

Я буду оценивать каждый метод, исходя из нескольких факторов:

  • частота использования: легкость настройки и обслуживания;
  • безопасность: сложность идентификации для постороннего человека;
  • комфорт: простота идентификации для пользователя аккаунта.

Каким образом поступить, если не получается зайти в zoom

В случае популярного сервиса для общения Зум и проблем с вводом пароля для входа в конференцию рекомендуем сделать следующее:

  • Перезагрузите ваш ПК (смартфон);
  • Проверьте правильность введения пароля. Зум использует два вида пароля – цифровой и циферно-буквенный. Убедитесь, что не произошло подмены;
  • Перед вводом пароля авторизуйтесь в Зум;
  • Вводите пароль вновь и вновь пока не произойдёт вход (при условии, что вы уверены в правильном наборе пароля);
  • Полностью деинсталлируйте Зум и почистите реестр от мусора (используйте CCleaner и аналоги). Перезагрузите устройство, и установите Zoom вновь;
  • Попросите администратора конференции активировать опцию « Разрешить удалённым участникам повторное подключение »;
  • Убедитесь, что вы используете последнюю версию приложения (в случае мобильной версии). При необходимости перейдите в Плей Маркет (Эп Стор), и обновите приложение; Аутентификация пользователя в PHP — Учебник по PHP — HTML Academy
  • Почистите кэш и данные мобильного приложения Зум;
  • Запустите какой-либо текстовый редактор (например, Блокнот) и наберите пароль там. Убедитесь, что вы его набрали правильно, затем выделите, скопируйте, и перенесите в поле для ввода данных в Зум. Попробуйте войти в конференцию.

Кодовая фраза

Аутентификация пользователя в PHP — Учебник по PHP — HTML Academy

Секретные фразы безопаснее паролей, их легче запомнить. Об этом пишут уже больше десяти лет: от статьи «
Пароли-слова против паролей-фраз» в 2005 году до «Почему секретные фразы удобнее для пользователей, чем пароли» в 2022-м.

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

Хотите доказательств?
Zxcvbn — это проект Dropbox, определяющий надежность пароля. Другие сайты могут использовать Zxcvbn как определитель надежности пароля с открытым исходным кодом. В этой статье Dropbox есть статистика и сведения об истинной надежности различных паролей.

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

Впервые я использовал пароли-фразы с компанией интернет-банкинга
Simple, которая приветствует эксперименты и новые технологии, и они показали себя прекрасно. Мою фразу-пароль просто запомнить и легко набрать — особенно на мобильном телефоне.

Права доступа

Права доступа выдаются клиенту в виде scope. Scope – это параметр, который состоит из разделённых пробелами строк — scope-token.

Каждый из scope-token представляет определённые права, выдающиеся клиенту. Например, scope-token doc_read может предоставлять доступ на чтение к какому-то документу на resource server, а employee — доступ к функционалу приложения только для работников фирмы. Итоговый scope может выглядеть так: email doc_read employee.

В OAuth 2.0 мы сами создаём scope-token, настраивая их под свои нужды. Имена scope-token ограничиваются только фантазией и двумя символами таблицы ASCII — ” и .

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

Причины ошибки «пароль неверный»

Данную проблему можно встретить на различных устройствах, системах, веб-ресурсах. Она довольно распространена, и несмотря на разнообразие платформ всё многообразие причин можно свести примерно к следующему:

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

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

Проблемы


Первая версия Auth — часть монолита. Он использует свой собственный протокол общения с сервисами. Такая «схема» была необходима в тот момент, но за несколько лет работы проявились проблемы.

Auth — часть монолита. Следовательно, сервис привязан к релизному циклу, что лишает возможности независимой разработки и деплоя. Кроме того, придется разворачивать весь монолит, если захотелось развернуть Auth, например, при масштабировании сервиса.

Dodo IS зависит от Auth. В старой реализации внешние сервисы обращаются к Auth при каждом действии пользователя, чтобы валидировать данные о нём. Настолько сильная привязка может привести к остановке работы всей Dodo IS, если Auth «приляжет» по какой-то причине.

Auth зависит от Redis. Притом достаточно сильно — неисправность работы Redis’а приведёт к падению Auth’а. Мы используем Azure Redis, для которого заявленный SLA 99,9%. Это значит, что сервис может быть недоступен до 44 минут в месяц. Такие простои не позволительны.

Текущая реализация Auth использует свой протокол аутентификации, не опираясь на стандарты. В большинстве своих сервисов мы используем C# (если говорим о backend) и у нас нет проблем с поддержкой библиотеки для нашего протокола. Но если вдруг появятся сервисы на Python, Go или Rust, разработка и поддержка библиотек под эти языки потребует дополнительных затрат времени и принесет дополнительные сложности.

Текущий Auth использует схему Roles Based Access Control, которая базируется на ролях. Обычно с ролью выдаётся полный доступ к определённому сервису, вместо привязки к конкретному функционалу. Например, в пиццериях есть заместители управляющего, которые могут вести определенные проекты: составлять графики или учитывать сырьё.

Проблемы подтолкнули к тому, чтобы спроектировать и написать новую версию Auth. На старте проекта мы потратили 3 недели только на изучение стандартов авторизации и аутентификации OAuth 2.0 и OpenID Connect 1.0. 

Примечание. Утрированно, статья — это пересказ RFC, который приходилось перечитывать несколько раз, чтобы понять, что происходит вокруг. Здесь я постарался уйти от этой сложности и рассказать всё максимально просто, структурировано, кратко и без описания сложных вещей, например, какие символы может содержать в себе ответ сервиса.

Схема на базе протокола srp

SRP — протокол парольной аутентификации, устойчивый к прослушиванию и MITM-атаке и не требующий третьей доверенной стороны. Имеет свой RFC2945. Есть производные от него стандарты для протоколов Telnet, TLS. Единственный из представленных, который проводит окончательную взаимную авторизацию обеих сторон. Хорошо описан как в Википедии, так и на Хабре пользователем @datacompboy.

Тем не менее, для генерации секретного ключа x протокол использует устаревшие подходы: (уже  не криптостойкую) функцию SHA-1 и  простую схему хеширования: x = hash(salt | hash(login | ‘:’ | pass). В свете современных тенденций к взлому паролей брутфорсом офлайн на специализированных ПЛИС или арендованных кластерах, данный подход должен быть улучшен, использованием scrypt.

Для реализации схемы нам понадобятся: большое простое число N, генератор g мультипликативной группы Z*N и параметр k = hash(N, g). В качестве g и N стороны используют числа, определенные в RFC-5054. Так, например, g = 2, а «мультипликативная группа» – это просто степени двойки; точнее их остатки по модулю N.

Процесс регистрации пользователя в системе:

  1. Клиент отправляет серверу свой login и свою 256-битную версию соли saltC.

  2. Сервер генерирует свою 256-битную версию соли saltS для пользователя login.

  3. Клиент формирует общую 256-битную соль: salt = saltC ^ saltS.

  4. Клиент вычисляет секретный 256-битный ключ x = scrypt(password, salt) от своего пароля

  5. Клиент вычисляет верификатор пароля V = gx (mod N).

  6. Клиент посылает на сервер пару (saltC, V).

  7. Сервер вычисляет общую соль salt аналогично клиенту в п. 3.

  8. Сервер хранит учетные данные пользователя в форме: login, salt, V.

Процесс авторизации пользователя в системе:

  1. Клиент формирует случайное 256-битное число a и вычисляет 2048-битное A = ga (mod N).

  2. Клиент делает запрос на сервер со своим login, и числом А.

  3. Сервер формирует случайное 256-битное число b и вычисляет 2048-битное B = (kv gb) (mod N).

  4. Сервер посылает клиенту пару (salt, B).

  5. Обе стороны вычисляют u = hash(A | B). В оригинальном RFC указано, что параметр u – 32-битное беззнаковое, получаемое от результата примененной хеш-функции hash(A | B).

  6. Пользователь вычисляет свой ключ x на основе пароля и соли, аналогично пп. 4 процесса регистрации.

  7. Пользователь вычисляет сессионный ключ K следующим образом: S = (B – kgx)a ux (mod N); K = hash(S).

  8. Сервер вычисляет сессионный ключ K следующим образом: S = (Avu)b (mod N); K = hash(S).

  9. Пользователь вычисляет M1 = hash( hash(N) ^ hash(g) | hash(login) | salt | A | B | K ) и отправляет на сервер.

  10. Сервер дождавшись от пользователя M1, проверяет его, производя аналогичные п. 9 вычисления.

  11. Сервер вычисляет M2 = hash( A | M1 | K ) и отправляет клиенту.

  12. Клиент проверяет M2 сервера. На этом этапе аутентификация считается завершенной.

В функции hash операция | означает конкатенацию аргументов. Если предполагается, что ключ K не будет использоваться в дальнейшем взаимодействии (например, для шифрования или аутентификации пакетов), то пп. 9-12 к исполнению обязательны. А если будет, то проверка излишняя, т.к. несогласованный ключ не позволит проводить корректное взаимодействие. Но я бы всё-таки оставил эти пункты обязательными.

Согласно спецификации, пользователь должен прервать аутентификацию, если получил B = 0 (mod N) или u = 0. (Полагаю, что B не должно быть также равно –kV, т.к. в этом случае клиент получит S = 0a ux (mod N) = 0).

Сервер должен прервать аутентификацию, если получил A = 0 (mod N). Клиент должен первым доказать, что получил тот же ключ K. Если клиенту это не удалось, сервер должен прервать аутентификацию, без своего доказательства K.

Токены

Токен в OAuth 2.0 — это строка, непрозрачная для клиента. Обычно строка выглядит как случайно сгенерированная — её формат не имеет значения для клиента. Токен — это ключ доступа к чему-либо, например, к защищённому ресурсу (access token) или к новому токену (refresh Token).

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

Refresh token опционален и доступен только для confedential клиентов. Пользуясь опциональностью токена, в некоторых реализациях время жизни access token сделано очень большим, а refresh token вообще не используется, чтобы не заморачиваться с обновлением.

За access token закреплён определённый набор прав доступа, который выдаётся клиенту во время авторизации. Давайте разберёмся, как выглядят права доступа в OAuth 2.0.

Форма авторизации на простом html с пояснениями

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

Базовая разметка HTML для простой формы авторизации:

<div class="form_auth_block">
  <div class="form_auth_block_content">
    <p class="form_auth_block_head_text">Авторизация</p>
    <form class="form_auth_style" action="#" method="post">
      <label>Введите Ваш имейл</label>
      <input type="email" name="auth_email" placeholder="Введите Ваш имейл" required >
      <label>Введите Ваш пароль</label>
      <input type="password" name="auth_pass" placeholder="Введите пароль" required >
      <button class="form_auth_button" type="submit" name="form_auth_submit">Войти</button>
    </form>
  </div>
</div>

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

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

Placeholder — простым словом “тег подсказка”, он дает возможность указать для пользователя что ему требуется сделать, что разрешено, а что нет. Можно указать любое значение. Обратите внимание что тег placeholder можно изменить с помощью стилей CSS.

Обратите внимание что в input так же задано свойство name, оно необходимо для последующей работы с формой, когда дело доходит до ее обработки на сервере. Это значение нужно делать уникальным и желательно схожим по названию отражающем его сущность. Если это форма авторизации, то логичнее всего задать name=”auth_email”, таким образом мы будем понимать что это свойство отвечает за передачу email адреса из формы авторизации. Многие новички в последующем делают частую ошибку работая с обработкой этих данных на сервере, особенно работая по паттерну MVC, когда в контроллере срабатывает событие к примеру submit а данные свойства name остаются везде одинаковые к примеру name=”email”.

Простые стили к форме авторизации без адаптации под мобильные устройства:

.form_auth_block{
    width: 500px;
    height: 500px;
    margin: 0 auto;
    background: url(http://www.dailycompass.org/wp-content/uploads/2022/01/Bubbles.jpg);
    background-size: cover;
    border-radius: 4px;
}
.form_auth_block_content{
  padding-top: 15%;
}
.form_auth_block_head_text{
    display: block;
    text-align: center;
    padding: 10px;
    font-size: 20px;
    font-weight: 600;
    background: #ffffff;
    opacity: 0.7;
}
.form_auth_block label{
    display: block;
    text-align: center;
    padding: 10px;
    background: #ffffff;
    opacity: 0.7;
    font-weight: 600;
    margin-bottom: 10px;
    margin-top: 10px;
}
.form_auth_block input{
  display: block;
  margin: 0 auto;
  width: 80%;
  height: 45px;
  border-radius: 10px;  
  border:none;
  outline: none;
}
input:focus {
  color: #000000;
  border-radius: 10px;
  border: 2px solid #436fea;
}
.form_auth_button{
    display: block;
    width: 80%;
    margin: 0 auto;
    margin-top: 10px;
    border-radius: 10px;
    height: 35px;
    border: none;
    cursor: pointer;
}
::-webkit-input-placeholder {color:#3f3f44; padding-left: 10px;} // Это стили для placeholder
::-moz-placeholder          {color:#3f3f44; padding-left: 10px;} // Это стили для placeholder
:-moz-placeholder           {color:#3f3f44; padding-left: 10px;} // Это стили для placeholder
:-ms-input-placeholder      {color:#3f3f44; padding-left: 10px;} // Это стили для placeholder

И вот что у нас получилось в итоге:

image

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

Подведём итоги

Параметр / Схема

1. Симметричная на базе HASH

2. На базе ECDSA

3. SRP-6a

Скорость

Проверка на сервере реализуется быстрее

Проверка подписи на стороне сервера в 2 раза медленнее клиента

Медленная, требует длинной арифметики и 4 пакета для завершения аутентификации

Технические сложности

Отсутствуют; может быть реализована на нативном js; работает достаточно быстро.

Отсутствует поддержка произвольной кривой в WebCryptoApi на клиенте

Уже никаких

Потенциальные уязвимости

Уязвима к компрометации БД и последующему контролю канала сервера; уязвима в процессе регистрации пользователя

Существуют классы уязвимых эллиптических кривых. Методики оценки безопасности кривых ещё не разработано. Вероятность, что выбрана «слабая» кривая, всегда остается.

Задача решения дискретного логарифма может быть решена теоретически; надежность базируется на сложности факторизации N; числа N, g, k известны всем.

Обратить особое внимание на

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

Числа A, B не должны быть равны 0 и 0, –vk соответственно.

Защита от пассивного MitM

да (но только не в момент регистрации)

да

да

Защита от активного MitM

да (только, если учетные данные не компрометированы)

да

да

Защита пароля при компрометации БД

да

да

да

Защита после компрометации БД и прослушивании канала

нет

да

да

Препятствие «легальному» доступу злоумышленника после компрометации БД

да

да

да

Взаимная аутентификация сторон

нет

нет

да

Защита от фишинга (попытка злоумышленника выдать себя за легальный сервер)

нет

нет

да

Требует наличие какого-либо доп. защищенного канала при регистрации клиента?

да

нет

нет

Защита слабых паролей в момент авторизации

нет

да

да

Защита от владельцев ЦОД

нет

нет

нет

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *