Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > JavaScript: Общие вопросы > Безопасная авторизация с использованием ajax и md5 |
Автор: _Dargin_ 9.3.2008, 21:05 |
Доброго времени суток уважаемые винградовцы. Сразу бы хотелось заметить, что тема не боян, а логическое продолжение очень похожей темы в разделе PHP, http://forum.vingrad.ru/forum/topic-175317.html. Просто хотелось бы поделиться своими наработками, надеюсь, модераторы форума меня поддержат. Цель этой статейки объяснить, как можно очень просто создать быструю и защищенную авторизацию пользователя используя ajax и md5. Про то где держать данные пользователя говорилось очень много, кто не знает вкратце это либо кукисы с привязкой к IP и очень ограниченным временем, либо для параноиков в сессии ![]() Главная цель это защита от перехвата post запроса вирусами. Обычно у разработчика есть выбор: использовать стандартную авторизацию, которая стоит почти на всех CMS и ничем не защищена или защищенные протоколы. Зачастую 2 либо не очень удобно ставить на «простенькие» сайты, либо просто лень ![]() Суть сей защиты очень проста, нужно хешировать передаваемый пароль на стороне клиента так, что бы его нельзя было переслать повторно (не важно откуда) и собрать такой же хеш можно было спокойно на сервере. Есть довольно простое решение: Сервер передаёт хеш IP и форму, пользователь вводит пароль и скрипт считает хеш(хеш IP + хеш(введеный пароль)) и передает вместе с логином на сервер. На сервере находится запись с таким логином и считается хеш аналогично как и на стороне клиента, если хеши совпадают, значит пароль верен (если сейчас кто-то вспомнил про хеш в мускуле, то мое мнение по этому поводу читайте в конце). Таким образом, повторная отправка возможна только при аналогичном IP. Если ваш сайт простенький то такой защиты хватит за глаза. НО, если вы разрабатываете деловой сайт, и защита играет не последнюю роль, то стоит призадуматься. Большинство офисов выходят в интернет через прокси, а следовательно у всего здания будет одинаковый IP. Методов борьбы несколько, можно просто отправлять хеш IP с привязкой ко времени например: хеш(«гггг-мм-дд чч-мм + IP»), а на сервере просто перебрать такой же хешь с этой, предыдущей и предпредыдущей минутой. Таким образом, повторная отправка возможно тока в течение 2-3 минут. По сути это решает проблему, но этот метод мне не очень нравится. Я предпочетаю использовать авторизацию с картинкой. Это тоже не сложно, есть обычная проверка цифрами на картинке - антибот, но свою функцию она как таковая не исполняет. Итак, сервер в сессию придумывает рандомом число и отправляет клиенту: 1 хеш IP, 2 хеш кода картинки (не обязательно). Пользователь вводит данные и сабмитит, скрипт сначала стандартно проверяет поля на заполненость, потом смотрит, равны ли хеш кода картинки хешу (введенный код пользователя), если нет, то предупреждает пользователя, это конечно не обязательно, но очень удобно. Данные в этом случае отправляются так хеш(хеш IP+введенные цифры с картинки(! не хеш естественно)+хеш(пароля)) сервер имеет все эти данные и без труда их сверяет. Если все это понять, то человеку знакомому с ajax понадобится меньше часа на реализацию сего. А теперь представьте себе хакера, который ночью пробрался в офис жертвы, полностью ознакомлен с вашей системой защиты и пытается отправлять данные до тех пор пока не получит такой же код картинки ![]() ![]() ![]() Рассуждение о данных на сервере. Человек знакомый с этой проблемой сразу подметит, что если кто-то выкрадет хеш пароля с мускула, то после некоторых махинаций с скриптом заполучит себе доступ. Но логично ли это??? эту защиту обычно называют «защитой от своих», почему? а все просто. Если ваш сайт имеет хотя бы админку, то ему нужен полный доступ к мускулу (права на запись и чтение) и если хакер не дай бог ![]() ![]() ![]() Так же хотелось бы поделится скриптом, который считает md5, чтоб не искать в инете, думаю будет полезен. Удачи в реализации, надеюсь помог хоть кому то сделать интернет безопасней. |
Автор: v2v 9.3.2008, 21:35 |
всё верно только в схожих протоколах аутентификации вместо ИП, даты/времени просто используют случайное число сгенерированное сервером и отправленное клиенту, а дальше всё также. |
Автор: Sardar 9.3.2008, 22:20 |
Хеширование паролей - техника, используемая всеми не первый десяток лет... ![]() И на этом форуме тоже. Кстати md5 коллизия подбирается за 8 часов по моему, лучше sha1 (который тоже по моему успешно атакован). Лучше реализовать blowfish, это симметричный ключ. Сервер генерит рандомное длинное значение и отправляет клиенту. Клиент из этого генерит другое значение согласно известному правилу (резко усложняет анализ зашифрованного сообщения), шифрует своим ключём и отправляет на сервер. Сервер декодирует, выполняет такое же преобразование у себя, сравнивает. Если совпало, значит клиент действительно владеет ключём. Blowfish - свободный алгоритм, до сих пор без особо успешных атак. Заметим что при таком подходе весь код открыт, всё известно, кроме ключа - известного только пользователю. Владение ключём - признак принадлежности к профилю на сервере. http://ohdave.com/rsa/ тоже возможна, но это перебор ![]() |
Автор: smartov 9.3.2008, 23:25 |
_Dargin_, Ярко ![]() ![]() Добавлено через 13 секунд А так статейка нормальная. |
Автор: SelenIT 9.3.2008, 23:40 |
smartov, |
Автор: Deepthroat 2.4.2008, 00:25 |
Как-то я уже поднимал на этом форуме проблему безопасной авторизации. Проблема была в том, что либо пароль хранится на сервере в открытом виде, а передается в измененном, либо на сервере хранится хеш, но передается пароль в открытом виде. Сейчас я, наконец нашел способ (спасибо автору): - на сервере храним md5(pass) - серверу передаем md5(R || md5(pass) || IP) Время особо нет смысла передавать, так как само время сессии ограничено. А вот ограничение на количество попыток логина ввести стоит, чтобы исключить перебор. Если хранить пароль на сервере можно, то передавать его лучше с использованием http://ru.wikipedia.org/wiki/HMAC: md5(pass XOR opad, md5(pass XOR ipad, R)) в Википедии все параметры описаны. Хотя, можно адаптировать и для моего случая, когда пароль не хранится. Делать, к примеру, не pass XOR <value>, а md5(pass || <value>), тогда получим что-то вроде md5(md5(pass, opad), md5(md5(pass, ipad), R)) но на сервере придется хранить уже два значения - P1 = md5(pass, opad) и P2 = md5(pass, ipad). А если и IP использовать, то получим: md5(P1, md5(P2, R), IP). Слишком много расчетов - это даже плюс, так как замедляет перебор, а пользователю один раз подождать не влом. Итак, резюмруя. 1. На сервере храним login, P1 = md5(pass, opad), P2 = md5(pass, ipad), где opad и ipad - константы. 2. Пользователь хочет залогиниться. Он отправляет login. 3. Сервер формирует случайное число R и отправляет его клиенту вместе с его IP. 4. Клиент формирует значение md5(P1, md5(P2, R), IP) = md5(md5(pass, opad), md5(md5(pass, ipad), R), IP) и отправляет серверу. 5. Сервер тоже формирует значение md5(P1, md5(P2, R), IP) и сверяет его с полученным. При этом, R хранится в сессии, а IP вычисляется заново. 6. Даем пользователю попыток 5, затем баним на 1 минуту. Преимущества: (+) Пароли в открытом виде не хранятся и не передаются. Недостатки: (-) Возрастают накладные расходы на хранение и время вычисления, хотя наш своеобразный HMAC не намного сильнее простого md5(R, md5(pass), IP) (-) Если хацкер украдет хеши с сервера, то он все равно сможет войти, хоть и никогда не узнает пароля. С учетом второго недостатка спрашивается, а в чем же преимущество хранить хеши вместо паролей? Ведь кража и паролей, и хешей приведет к тому, что хацкер сможет залогиниться в системе! А преимущество в том, что многие пользователи используют один и тот же пароль с логином для всех своих учетных записей. Так что в нашем случае, взломав одну учетную запись, хацкер не получит доступ ко всему, что есть у пользователя. |
Автор: _Dargin_ 3.4.2008, 09:25 |
Собственно описнаное выше это одно и тоже что вариант с картинкой, только вместо картинки используется цифра. Вариант с картинкой удобнее тем что сама цифра не передается открытым способом и это также защищает от перебора. Хотя картинка может быть и неудобна пользователю. А насчет скорости, так это работает намного быстрей обычной регистрации, в основном засчет ajaxа. |
Автор: Deepthroat 13.4.2008, 23:19 |
Основная проблема в том, что 100%-ной гарантии как не было, так и нет. Либо мы защищаемся от кражи данных с сервера, либо от перехвата трафика - одновременно защититься от всего не выйдет. А так, вообще, нормально. Хоть что-то. |