LINUX.ORG.RU

Способ аутентификации на жабоскрипте

 , , ,


0

2

Обычно для аутентификации на веб-сервисе я пользовался следующим алгоритмом: после нажатия на кнопочку login пользователь перебрасывался на https-страничку ввода логина-пароля, сервер сверял хэш пароля с хэшем из БД для соответствующего логина и если все ОК, отсылал пользователю куку и возвращал его на нешифрованную страничку.

Но с https постоянная проблема: надо генерировать свои сертификаты и объяснить пользователю, что при запросе браузера на подтверждение, нужно жамкнуть «да».

Тут я придумал такое решение, работающее безо всяких SSL: пользователь вводит логин-пароль, получает от сервера некий случайный ключ, прислюнивает в качестве соли хэш своего пароля и полученный хэш отправляет обратно серверу. У того уже есть хэш пароля, и он выполняет такую же операцию. Если результат одинаковый, пользователю высылается ключ, который сохраняется не в куках, а в localStorage (по-моему, это удобней). При последующих соединениях пользователь лишь указывает этот ключ. А сам ключ имеет определенное время жизни. При желании его можно тем же самым методом обновлять, не требуя у пользователя перелогина (если, конечно, он не закроет страничку и не выждет времени отзыва ключа).

Как вам такая идея? Взлетит? Больше всего меня беспокоит устойчивость метода к атаке man-in-the-middle.

☆☆☆☆☆

Взлетит. Устойчивость к man-in-the-middle такая же, как в случае с самосгенерированным сертификатом (т.е. никакой).

Minoru ★★★
()
Ответ на: комментарий от Minoru

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

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

Eddy_Em ☆☆☆☆☆
() автор топика

Окей, есть Алиса (клиент), Боб (сервер) и Чак (MiM).

Чак выдает себя за Боба. Алиса хочет авторизироваться. Чак запрашивает у Боба некий случайный ключ. Чак отправляет Алисе его же. Алиса прислюнивает в качестве соли хэш своего пароля и полученный хэш отправляет обратно (Чаку). Чак отправляет заслюненый хэш Бобу. Боб говорит: «Верно!», и отправляет Чаку ключ, который сохраняется в localStorage. Чак передает его Алисе.

И так, этот ключ теперь знают и Алиса, и Чак.

noomorph
()
Ответ на: комментарий от noomorph

Хм, а и правда. Но сколько нужно усилий потратить, чтобы такой перехват сделать?

Eddy_Em ☆☆☆☆☆
() автор топика

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

А не проще купить сертификат?

generator ★★★
()
Ответ на: комментарий от anonymous

Что-то там очень много расписано, но я не уловил сути механизма. Вкратце: как он работает? Нужна третья сторона что ли?

Eddy_Em ☆☆☆☆☆
() автор топика

как сервер узнает значение ключа в случае localstorage без кук? светить ключ в урле? тогда теряется смысл подхода. Проблема в том, что от кук не так просто избавиться. По крайней мере мне не очевиден способ замены кук при помощи localstorage - только если что-то вычислять как-то, но что мешает другому так сделать?

anonymous
()
Ответ на: комментарий от anonymous

как сервер узнает значение ключа в случае localstorage без кук?

Ключ хранится в БД. Точно так же, как и в случае кук. Передаем серверу через вебсокет или POST-запросом — разницы никакой, т.к. в случае с куками та же ситуация: ключ идет открытым текстом.

мне не очевиден способ замены кук при помощи localstorage

Элементарно: то, что раньше хранилось в куках, теперь хранится в localstorage.

Eddy_Em ☆☆☆☆☆
() автор топика

Ты придумал нечто похожее на CSRF-токен

deep-purple ★★★★★
()
Ответ на: комментарий от noomorph

Но зачем столько телодвижений? Чак может просто мониторить траффик между Алисой и Бобом в поисках ключа. Собственно никакого профита от такой системы нет.

ki11obyte
()

А по теме - бред. В чем смысл сего действа? Если кто-то прослушивает линию, то он спокойно читает все эти твои странные манипуляции. К чему это шаманство? Можно прислать ключ, можно прислать промежуточный ключ, а потом ключ, можно прислать 10 промежуточных ключей, а потом ключ.. в определенный момент ты все-равно отправишь «итоговый» ключ и именно его возьмет себе злоумышленник предварительно покрутив у виска.

special-k ★★★
()
Ответ на: комментарий от Eddy_Em

Ну насчет передавать ключ через-POST неудобно, в случае кук проще: значение прицеплено в заголовках. В общем такое применение localStorage то-же самое что и с куками, только вид сбоку. Хотя localStorage современно, молодежно, но не даёт существенных плюсов.

Интересен вариант, когда значение ключа не передаётся по каналам связи. Это не будет работать в случае передачи шифрованного ключа - 3-ей стороне нчито не мешает этим воспользоваться. Нужен шифрованный канал для передачи токена, а это то-же самое что стандартный шифрованный канал.

Хочешь без шифрования канала? Передавай шифрованный контент, ключом, который в localStorage. Это будет работать, при условии, что значение ключа знает только оконечный браузер и сервер. Это можно реализовать.

Осталось за малым: клиенты для шифрования на сервере и в браузере. Какая нибудь реализация «рыбных» шифров или мифический GPG-js.

anonymous
()
Ответ на: комментарий от special-k

Тебе и xtraeft: затем, что черезжопно это — скакать туда-сюда (то на https, то обратно). Да и полдня же тратить, чтобы https поднять на новом компьютере... Нафиг оно нужно?

А покупать SSL-сертификаты ради внутренней морды управления железякой — бред!

Eddy_Em ☆☆☆☆☆
() автор топика

Полезного по теме: юзай что-нить типа этого https://github.com/digitalbazaar/forge Или, как вариант, передавать хешированные пароли https://github.com/blueimp/JavaScript-MD5 , можешь передавать на страницу соль, чтобы захешировать ею пароль, и только после этого отправлять на сервер. Тогда ты защитишь не сессию пользователя, но пароль (можно и логин).

special-k ★★★
()
Ответ на: комментарий от anonymous

Дык, просто я от CGI перехожу к вебсокетам. Можно, конечно, и к вебсокету куку прислюнить, но что-то нет желания: можно же напрямую отправлять данные!

И еще: ведь SSL-аутентификация по сути точно такая же! И ее точно также M-I-M может взломать!!!

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

На сервере-то фигня, а вот в браузере... Да и смысл все шифровать? Нужно лишь при установке соединения сделать проверку свой-чужой, и все.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от special-k

юзай что-нить типа этого https://github.com/digitalbazaar/forge

Почему там кода так дофига? Если больше двух страниц жабокода нужно будет, то нафиг такой способ! Это ж извращение!!!

Или, как вариант, передавать хешированные пароли https://github.com/blueimp/JavaScript-MD5

Во, это уже поближе.

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

Eddy_Em ☆☆☆☆☆
() автор топика

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

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

special-k ★★★
()
Последнее исправление: special-k (всего исправлений: 3)
Ответ на: комментарий от special-k

Ну, это почти то же самое. Просто уменьшается количество проверок. В принципе, да: проще.

Итак, результирующая схема (сервер хранит логин в явном виде, а пароль в виде хэша):

  • сервер отсылает "соль" клиенту, а сам, стыкуя вместе логин и хэш пароля и хэшируя их этой "солью" получает ключ сессии;
  • клиент этой "солью" тоже вычисляет ключ сессии и отсылает серверу;
  • сервер проверяет — если ОК, то позволяет, скажем, минут 5-10 сессии продержаться, иначе — шлет лесом;
  • по истечению таймаута опять повторяем вычисление нового ключа.
Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

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

Шифрование для сервера и браузера не фигня для сервера: нужна схема, адекватно и одинаково работающая на обеих сторонах и желательно в стиле mcrypt

anonymous
()
Ответ на: комментарий от Eddy_Em

Почему там кода так дофига?

Реализация SSL (вроде).

special-k ★★★
()
Ответ на: комментарий от Eddy_Em

Ну, это почти то же самое.

Да, но в первом случае защиты сессии не было вообще, а тут какая-никакая.. в общем-то нормальная вполне.. :)

special-k ★★★
()
Ответ на: комментарий от Eddy_Em

Да и полдня же тратить, чтобы https поднять на новом компьютере...

Полдня?

А покупать SSL-сертификаты ради внутренней морды управления железякой — бред!

Это да, тем более к ip ты его не привяжешь.

xtraeft ★★☆☆
()
Ответ на: комментарий от Eddy_Em

тогда уж ключи должны генериться одноразовые, а не с таймаутом...

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

anonymous
()

подсмотрят хеш твоего пароля и будут его подставлять, защиты 0, передавай уж сразу открытым текстом :)

anonymous
()
Ответ на: комментарий от anonymous

если это не критично-тогда зачем это все?

Чтобы студенты, которым делать нечего, не могли управлять железякой.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от anonymous

Когда куки угоняют - тот же принцип. Потому нет разницы, где ты ключик хранишь, в куке или в строке запроса.

deep-purple ★★★★★
()
Ответ на: комментарий от Eddy_Em

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

anonymous
()
Ответ на: комментарий от anonymous

Спасибо, это тоже пригодится.

Eddy_Em ☆☆☆☆☆
() автор топика

устойчивость метода к атаке man-in-the-middle.

нулевая, mitm может поменять весь твой хитрый javascript на заглушку, шлющую пароль напрямую ему. Кстати, именно поэтому каждый сайт, где можно залогиниться, обязан использовать HTTPS не только на странице логина, но и вообще по всему сайту.

Но с https постоянная проблема: надо генерировать свои сертификаты и объяснить пользователю, что при запросе браузера на подтверждение, нужно жамкнуть «да».

startssl, не? Какое подтверждение?

anonymous
()
Ответ на: комментарий от anonymous

mitm может поменять весь твой хитрый javascript на заглушку, шлющую пароль напрямую ему

Йок! И действительно. Что-то об этом я совсем не подумал!

Но чертовы сертификаты настраивать... А, ладно, понастраиваю. Можно вообще постоянно на https сидеть, и вебсокет тоже SSL'ем шифровать, раз уж все равно придется сертификаты генерировать.

Eddy_Em ☆☆☆☆☆
() автор топика

Обычно для аутентификации на веб-сервисе я пользовался следующим алгоритмом: после нажатия на кнопочку login пользователь перебрасывался на https-страничку ввода логина-пароля, <…> и если все ОК, отсылал пользователю куку и возвращал его на нешифрованную страничку.

Так давно уже ни один нормальный сайт не делает. Так было модно в начале нулевых и только из экономии ресурсов (полное шифрование требовало больше). А сейчас то зачем так поступать? Ну ок, пароль от MIM защитишь, а остальные данные нет. Кукисы и прочее всё будет ему доступно.

i1atf
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.