Одноразовый ключ (Рейтинг: +5)

Печать RSS
Здравствуйте.
Мало кто конечно углубляется при написании интернет проекта о опасности передачи данных по незащищенным каналам, но рано или поздно нам приходится сталкиваться с проблемой перехвата данных. Особенно остро стоит эта проблема при регистрации и аутентификации пользователей, ведь часто данные передаются по каналам в открытом видел и хешируются на стороне сервера (редко встречал реализации md5 на JS, хотя сам всегда пользовался), реже передается хешь, при чем всегда один и тот же (так как обычно хешируется пароль или некие данные + пароль). Такой механизм имеет такую же уязвимость, что и передача открытого пароля, хеш можно перехватить и перебором найти пароль. Предлагаемый мной в данной статье способ не новый, но его суть в том, что пароль никогда не передается в открытом виде или в повторяющимся хеше (даже при регистраци). При каждой аутентификации хеш меняется, более того, в базе никогда не хранится пароль или хеш пароля, хранится связка пароля и случайного числа. Еще одним плюсом метода является то, что даже при использовании двух одинаковых паролей по каналам связи будут передаваться совершенно разные хеши этих паролей.
Плюсов у такого механизма много, но и минусы есть, основной это довольно большие затраты ресурсов клиента и сервера, другим минусом является необходимость перерегистрации пользователя (повторного ввода секретного ключа для обновления зерна и счетчика) при подходе счетчика к нулю.
И так в чем же состоит суть этой методики. Начну с терминов:
Секретный ключ - известная только пользователю последовательность символов (пароль);
Зерно (открытый ключ) - сгенерированная сервером последовательность из ~5 случайных символов, хранящаяся вместе с логином пользователя на сервере;
Итератор (счетчик) - текущее число итераций хеш функции. Хранится на сервере вместе с логином и зерном;
Алгоритмы метода: Регистрация - пользователь задает свой логин и передает его на сервер, сервер записывает его в базу и сразу генерирует зерно и устанавливает итератор данного пользователя в максимальное значение (на пример 300), после чего передает зерно и значение итератора клиенту. Теперь пользователь определяет свой пароль (секретный ключ), браузер получив пароль от пользователя и зерно с итератором от сервера создает связку пароль + зерно и применяет к данной связке хеш функцию (на пример md5), затем к полученному хешу применяет снова хеш функцию и так столько раз, сколько указано в итераторе. Полученную строку браузер передает на сервер. Сервер уменьшает значение итератора для заново пользователя на 1 и записывает полученный от него хеш к зерну, логину и итератору. Таким образом при регистрации пароль не передается в открытом виде и не хранится в базе в виде простой связки.
Аутентификация - пользователь вводит свой логин и передает его серверу, сервер находит данный логин в базе и передает пользователю его зерно и значение итератора. Пользователь теперь вводит пароль и браузер создает связку пароль + зерно и применяет на нее хеш функцию столько раз, сколько указано в итераторе. Полученный хеш он передает на сервер. Сервер применяет к нему хеш функцию еще один раз и сравнивает получившееся с хранимом у него хешем данного пользователя, если они одинаковы, то аутентификация считается успешной и сервер записывает полученный от пользователя хеш (который был до наложения на него сервером хеш функции) и заменяем им хранимый в базе хеш, а так же уменьшает значение итератора на 1. Таким образом при каждом входе пользователя будет применяться разное количество хеш обработок связки пароль + зерно, и за счет этого передаваемый хеш будет всегда разный. Более того даже при подходе итератора к нулю и необходимости заново перерегистрироваться, зерно уже будет другим и это будет приводит к созданию все новых хешей.
Добавил:
Рейтинг: +5
Просмотры: 1833
Комментарии (3) »