Насколько безопасна подпись основанная на хешировании данных с солью?
Допустим, у клиента сайта есть логин, который хранится в куки. Серверу необходимо при каждом запросе проверять авторизован ли пользователь, причём не прибегая к базе данных (для этого случая так же, не будет использовать кеширование в оперативной памяти, не будем использовать redis и подобное).
Короче, нужно сделать быструю проверку авторизации без использования БД. Очень удобно, просто и быстро можно сделать так:
1. Пользователь входит на сайт (указывает логин и пароль на странице авторизации)
2. Если логин и пароль верны, сервер берёт логин, например Test, конкатенирует его с какой-то сложной случайной строкой, например ZIvvWQOaGvjzjKSD, получает хеш:
3. Сервер возвращает новые куки клиента: Логин Test и подпись, полученная на втором шаге b67c9b06ab5....
Теперь серверу, чтобы проверить авторизацию, достаточно взять логин Test, который хранится в куки, вычислить его хеш с ключом и убедится, что эта же строка есть в куки. Понятно, что секретная строка одинакова для всех пользователей. Насколько безопасен такой алгоритм?
P.S Хочется использовать подобную вещь не только для быстрой проверки авторизации, но и для других целей. Есть смысл использовать этот алгоритм как подпись, или лучше использовать обычные алгоритмы?
Я бы не стал проверять авторизацию только по данным от клиента. В принципе. Сам способ генерации авторизационного токена вполне неплох, но имхо следует в него добавить некий секрет, известный только серверу, т.е. соль или её часть хранить в БД рядом с инфой об учетной записи клиента. Если вдруг статичная соль каким-то образом утечет, получите анонимную авторизацию под любой учеткой на сервере, включая несуществующие, с наличием динамической части такой проблемы не должно появиться. А экономить один запрос в БД на входной авторизации по мне нелогично, тем более, если проект не является хайлоадом (да и там оптимизации допустимы, включая хранение соответствия логин-соль где-то в памяти соседнего микросервиса).
В одном из своих проектов использовал такую штуку, чтобы проверять авторизован ли пользователь ещё перед созданием подключения к базе данных. Очень помогает во время ДДОС атак. Сначала проверяем авторизован ли человек (быстрой проверкой), если авторизован, то его лимит на кол-во запросов в секунду/минуту/час выше, чем у неавторизованного. Проверяем превысил ли человек лимит (данные хранятся в оперативной памяти), если нет, то создаём подключение к бд и продолжаем работу скрипта.
Bleno, то есть хайлоад таки есть. Тогда можно создавать две куки, одну для простой проверки, вторую для полноценной, и использовать простую проверку, если сессия пользователя активна. Но по идее это же выполняет обычный сессионный токен типа PHPSESSID, с той только разницей, что список сессий в этой схеме хранится не в БД, а в памяти веб/апп-сервера.
Во-первых ты путаешься в терминологии. Сначала ты называешь это "хешированием данных с солью", потом соль становится "какой-то сложной случайной строкой", потом уже это "хеш с ключом", а в конце оказывается, что строка -- секретная. Соль -- это средство уникализации хешей и защита от подбора хеша с помощью радужных таблиц, её значение не является секретным, но оно должно быть уникальным для каждого защищаемого объекта.
Во-вторых если "сложная случайная строка" общая для всех пользователей и используется так как ты описал, она просто становится частью пароля хешируемого без соли. Аутентифицированный пользователь получивший хеш для своего пароля может подобрать "сложную случайную строку" с помощью радужных таблиц.