Хранение паролей и базовая авторизация #
Документация #
Хранение паролей #
Для хранения паролей пользователей в любой информационной системе необходимо предпринимать меры по защите данной информации от потери. В случае потери списка пользователей злоумышленники не должны иметь простой возможности по получению паролей пользователей, т.к. пользователи имеют тенденцию к повторному использованию паролей между различными веб-приложениями.
Пароль также обладает интересной особенностью: не надо сохранять пароль целиком, достаточно иметь возможность сравнить пароль, который был введён пользователем при регистрации, с паролём, который был введён для авторизации в системе. Для решения этой задачи зачастую прибегают к хеш-функциям, которые формируют одинаковую хеш-строку для одинакового ввода данных.
flowchart LR login["Пароль регистрации"] auth["Пароль авторизации"] hash("Функция хеширования") log_hash["Хеш регистрации"] log_auth["Хеш авторизации"] login --> hash auth --> hash hash --> log_hash hash --> log_auth
Если применять функции хеширования «в лоб», тогда для взломщика надо будет не просто прочитать хеш, а перебрать строки, хеш-сумма которых будет совпадать с той, что записана в базе данных. Значительное улучшение, однако всё-равно позволяет достаточно легко найти оригинальный пароль.
Для улучшения защиты данных для перебора необходимо выполнить ещё пару улучшений:
- Увеличить количество итераций для выполнения алгоритма. Это затруднит прямой перебор. Внимание! не надо применять хеш-функцию к результату работы хеш-функции! Итерации выполняет сам алгоритм хеширования.
- Добавить секретную соль, которой производится расширение данных в пароле.
В результате алгоритм вычисления хеша будет следующим:
- получить пароль от пользователя;
- добавить к введённому паролю соль;
- применить к полученной строке хеш-функцию определённое количество итераций.
Затем вычисленный хеш либо необходимо сохранить в хранилище, либо сравнить с тем, что находится в базе данных.
Сохранение соли для паролей #
Соль для паролей нельзя хранить вместе с паролями, т.к. это полностью лишает её всяческого смысла. Её можно располагать в отдельном хранилище или поместить в настройках приложения. Таким образом для корректной работы системы потребуется корректная соль и хранилище паролей.
Согласно разрабатываемой архитектуре веб-приложения для хранения данной информации следует воспользоваться подсистемой настроек. При этом данная настройка не является частью настроек веб-сервера или доступа к хранилищу.
Использование функций хеширования в JVM #
JVM предоставляет средства для выполнения хеш-операций над данными. Они доступны через класс MessageDigest. Можете ознакомиться с краткой инструкцией по использованию данного класса в данной статье: https://habr.com/ru/articles/444974/. В качестве алгоритма хеширования используйте алгоритм SHA семейства SHA-2 или SHA-3.
Для преобразования набора байт к строке (для хранения) можно воспользоваться другим классом, предоставляемым JDK: HexFormat. Для его использования потребуются следующие методы:
of()
— для создания объекта классаHexFormat
.formatHex(byte[] bytes)
— для преобразования массива байт в строку.
HexFormat commaFormat = HexFormat.of()
byte[] bytes = {0, 1, 2, 3, 124, 125, 126, 127};
String str = commaFormat.formatHex(bytes);
Задача #
- Реализуйте хранилище для сохранения соли. Сформируйте соль для пароля. Соль должна быть достаточно большой длины, рекомендуется от 100 случайных символов.
- Добавьте новую сущность «Ученик». Он описывается следующими полями: имя пользователя, пароль, дата добавления.
- Реализуйте хранилище для данных сущностей приложения.
- Реализуйте процедуру добавления нового ученика.
- Добавьте страницу «управление пользователями», доступную через навигационную панель.
- На странице добавьте кнопку «добавить ученика».
- При нажатии на кнопку пользователю должна открыться форма с вводом данных. На форме должны присутствовать поля: имя пользователя и два поля для ввода пароля.
- При отправке данных с формы на уровне обработки данных формы, необходимо проверить равенство двух паролей, введённых пользователем.
- Создайте операцию добавлению нового пользователя в хранилище.
- В конструктор операции передайте ссылку на хранилище учеников.
- В конструктор операции передайте строку-соль, полученную из настроек.
- Для передачи соли из настроек передайте соль также в конструктор хранилища операций.
- В момент выполнения операции получите имя пользователя и пароль.
- Перед записью пароля в базу данных объедините её с солью.
- При записи данных в базу внутри SQL-выражения проведите преобразование солированного пароля в хеш-значение.
- Доработайте процедуру добавления нового треугольника.
- На странице добавления добавьте поле для ввода имени пользователя и пароля ученика.
- При добавлении треугольника проверьте, что введённый пароль соответствует указанному ученику. Если пароли не совпадают, то необходимо показать страницу добавления треугольника с сообщением об ошибке.
- Создайте операцию по проверке пароля пользователя.
- Операция должна принимать имя ученика, пароль и соль.
- В рамках операции должно проверяться соответствие имени ученика и хеш-суммы от пароля с солью с сохранёнными данными.