Как стать автором
Обновить

Комментарии 24

Сергей, спасибо что включаешь меня в соавторы, но по правде сказать я был тогда такой зелёный, что разве что мог послужить «подопытным кроликом». Шаги протокола несколько раз прокрутил в голове в процессе реализации, уязвимостей придумать так и не смог. А ещё мне до сих пор стыдно за CVE с nil-terminated string в MYSQL CHANGE USER который я в своё время проморгал.
Про велосипеды ранних 90-е еще можно понять, но сейчас их городить? Разве что потому, что SRP not invented here.
Нет, просто он неудобный. Все схемы с солью добавляют еще один round-trip к аутентификации. А этот SRP, похоже, даже два. Мы же, наоборот, старается уменьшить число round-trip-ов в протоколе, так что раздувать протокол не хотелось бы.
Он совершенно также дает плюс один round-trip, как и эти велосипеды. Но кроме всего прочего позволяет клиенту удостовериться что сервер тоже знает пароль. Да, последнее не стойко к компрометации серверной базы, но как минимум стойко к прослушке.
Можно посчитать.

В нашем протоколе так:
1. сервер→клиенту: «привет, вот scramble»
2. клиент→серверу: «username такой-то, пароль такой-то»
3. сервер→клиенту: «ok» (или «пошел на фиг»)

причем шаги 1 и 3 обязательны, плагин на них не может повлиять.

В SRP будет так:
1. сервер→клиенту: «привет»
2. клиент→серверу: "I and A"
3. сервер→клиенту: "s and B"
4. клиент→серверу: «вот мой M1»
5. сервер→клиенту: «ok, вот мой M2»

да, в плюс один можно уложиться.

Идентификация сервера — это хорошо, но в задачу не входило. Для этого можно включать SSL. Может потом сделаем и с идентификацией сервера.
По количеству запросов SRP практически такой же, единственная разница что в вашем случае серверу не нужно ждать первого авторизационного пакета, он может сразу выдать scramble. Честно говоря сомнительное ускорение. При этом SRP хорошо проанализирован, стандартизован и проверен. В нем учтены всевозможные векторы атаки. Его разрабатывали специалисты, его анализировали специалисты. Зачем городить самопал?

Первое правило криптографии: не изобретайте собственных алгоритмов.
А что djb думает по поводу того что вместо случайный 32 случайных байт ключ всего от силы 10 неслучайных?
Я, конечно, не спрашивал. Ну а что тут думать — плохо это, подобрать 10 неслучайных байт проще, чем 32 случайных. Но если без соли, то за случайность отвечает пользователь, мы тут ничего улучшить не можем. А соль увеличивает число round-trip-ов, поэтому ее пока что избегаем.

Кстати, вначале я использовал немодифицированный ed25519 и получал 32 «случайных» байта как SHA256(password). Потом решил, что лишний SHA256 случайности не добавит, и убрал :)
«Man-in-the-middle отдыхает»

Вопрос1:
А каким образом при регистрации пароль юзера первый раз передается на сервер?

Вопрос2,3:

— После авторизации, чем шифруется весь трафик между клиентом — сервером?

— Если MITM получит подписанный юзером scramble и переправит на сервер, после этого разве он не сможет выполнять любые команды от имени юзера? (актуально если нет шифрования трафика после авторизации или необходимости подписи всех команд отправляемых на сервер юзером)
1. Есть варианты. Обычно он передается открытым текстом и на сервере хешируется. Это не есть хорошо. Но можно хеш посчитать и локально, тогда на сервер попадет только хеш.

2. Или SSL или ничем, смотря как настроено.

3. Если SSL — то не сможет, если нет SSL — то сможет. В протоколе после аутентификации никакой защиты нет. Велосипедить свой собственный аналог OpenSSL не хочется, да и не нужно это никому — в смысле никто никогда за 20 лет это не просил.
Хм, тогда какой же здесь «Man-in-the-middle отдыхает»? :)

Если используется SSL то, вообще зачем нужен какой-то дополнительный протокол, просто клиент через SSL открыто (для сервера) посылает захешированный пароль и сервер пишет его в базу, а при авторизации тоже самое, клиент по SSL открыто (для сервера) отправляет хешированный пароль и сервер сравнивает его с хешем из БД. При взломе сервера пароли никто не получит. Это просто и надежно.

Если без SSL, то от MITM у вас защиты никакой нет, есть только защита от снифера.

Заранее распространенный файл с ключем/сертификатом сервера (например через официальный дистрибутив клиента) нужен как раз для защиты от MITM.
1. Ну как. Это протокол аутентификации. Как он работает — определяет плагин. Но он инкапсулирован в MySQL client-server protocol, и все равно все происходит по правилам этого протокола, который несколько шире, чем аутентификация, и плагин на него влиять не может (пока что. хотим это менять).

Инкапсуляция устроена так, что новые методы аутентификации можно добавлять когда угодно, это совместимости не ломает, перекомпиляции ни сервера ни клиентов не требует, даже перезапускать сервер не нужно — новые плагины можно подгрузить на лету и в сервер, и в клиентов.

В приведенном новом протоколе аутентификации MitM-у ловить нечего. За его пределами — да, можно. Но тут уже всю систему менять надо, то есть сам клиент-серверный протокол. Это задача совсем другого уровня, в 10.1 (да и в 10.2) это сделать невозможно.

2. Неее. Это как раз то, что мы исправляли в начале двухтысячных. При взломе сервера «кто-то» получит все хэши. И потом сможет их по SSL слать, пароли ему не нужны.

3. Защита он снифера у нас такая же как и от MitM. Во время собственно аутентификации —- ни MitM, ни сниффер ничего не получат. После — обоим путь открыт, если не использовать SSL.

4.Заранее распространенный файл от MitM-а не поможет, если сессия не шифруется. А она шифруется только, если включить SSL. Так что тут заранее распространенный файл бесполезен от слова совсем. Он нужен не для этого, а для аутентификации сервера клиенту. Чтоб клиент знал, что он подключается к правильному серверу. Но в том же вышеупомянутом SRP эта задача решена гораздо элегантнее, без всяких файлов. И через официальный дистрибутив ключи нельзя распространять, в том же весь смысл, чтоб у разных серверов были разные ключи.
2. Неее. Это как раз то, что мы исправляли в начале двухтысячных. При взломе сервера «кто-то» получит все хэши. И потом сможет их по SSL слать, пароли ему не нужны.
— Тут согласен

3. Защита он снифера у нас такая же как и от MitM. Во время собственно аутентификации —- ни MitM, ни сниффер ничего не получат. После — обоим путь открыт, если не использовать SSL.
— Тут ошибка. Защиты от MITM нет, так как если между клиентом и сервером стоит ПК, который во время аутентификации перехватывает пакеты и просто дублирует их для клиента и сервера, то в момент получения от клиента подписанного scramble и переправки его на сервер, злоумышленник полностью получает доступ с правами юзера. А например юзеру, он перешлет «ошибку подключения к серверу».
От снифера есть, т.к. пароль в открытом виде не передается, и подсмотренный подписанный юзером scramble ему не пригодится, так как при попытке авторизации scramble уже будет выслан другой.

4.Заранее распространенный файл от MitM-а не поможет, если сессия не шифруется.
— :) Так он же как раз и распространяется для шифрования сессии SSL при авторизации и защиты от MITM (подмены сервера).

5. И через официальный дистрибутив ключи нельзя распространять, в том же весь смысл, чтоб у разных серверов были разные ключи
— Вы видимо не поняли, «например через официальный дистрибутив клиента». Никто не мешает создать свой сертификат сервера, для своего клиент-серверного приложения и распространять этот сертификат со своим клиентским приложением, что бы клиент всегда подключался только к легальному серверу. Тут можно использовать даже самоподписанные сертификаты ибо ваш клиент — это по сути браузер, который сертификат нужного сервера уже считает доверенным. Создание сертификата даже можно вынести в отдельную ф-цию приложения, что бы, например, администраторы в разных компаниях, могли создавать свои корпоративные сертификаты для своих серверов и распространять их в дистрибутивах своих корпоративных клиентов.

Что бы ваш протокол авторизации был по надежности сравним с SRP, надо решить проблему указанную выше в пункте 3.
3. Согласен, но это то же, что и я говорил. Во время аутентификации ни снифер ни MitM не могут узнать пароль (или «информацию, эквивалентную паролю», как в примере с хэшем). После аутентификации MitM может посылать от имени юзера команды. А снифер может видеть все данные, что запрашивает юзер — без SSL после аутентификации защиты нет, тут надо весь протокол менять.

Вот, например, в новом sha256 протоколе в 5.7 если заранее не дать клиенту открытый ключ, он его запросит с сервера. MitM может этот ключ подменить своим и узнать пароль клиента, plain-text. Тут сама аутентификация уязвима к MitM. То же самое в SSL, если у клиента нет возможности проверить сертификат.

4. Нет, в sha256 плагине, файл используется только для шифрования пароля, не всей сессии. Аутентификационный плагин в принципе не может повлиять на всю сессию, он используется только для аутентификации. Так устроен протокол. Если использовать SSL (и проверять валидность сертификатов) то неважно как аутентифицировать, все равно SSL все зашифрует и обеспечит.

5. Да, если свой дистрибутив со своим сертификатом ­— то конечно, согласен.

6. Нет, SRP тут не причем. Если использовать SRP в рамках теперешнего протокола (и без SSL), то сессия все равно будет не зашифрованной и не защищенной от MitM. Вообще неважно насколько сложный, крутой и непробиваемый будет протокол аутентификации, если основной клиент-серверный протокол останется, какой есть. Надо сам протокол переделывать, плагином это не исправить.
Собственно мы говорим разными словами об одном и том же :)

«После аутентификации MitM может посылать от имени юзера команды.»
— А разве кто-то вообще может посылать команды до аутентификации? Просто перехват (компрометация) выполняется именно в момент отправки юзером подписанного scramble, т.е. в процессе аутентификации ибо scramble только для этого процесса и нужен. А команды естественно уже выполняются потом. Пароль MITM в процессе аутентификации юзера не узнал, но доступ получил.

Кстати, интересно, по вашему клиент-серверному протоколу, если после нормальной аутентификации юзера, хакер просто включит снифер и увидит ID авторизованной сессии юзера, он сможет по этому ID выполнять свои команды?

6. Нет, SRP тут не причем
— Ну, я имел в виду именно сравнение авторизации через SRP, и тем вариантом авторизации, который предложен в статье. В этом смысле отличие SRP в том, что он от MITM защищен. Безопасная работа уже с самой авторизованной сессией должна обеспечиваться протоколом передачи данных/команд.

Подскажите, почему выбор пал на ed25519 в качестве основного криптоалгоритма?

Если вы упомянули банки и их запросы, то для них более спокойно было бы если вы использовали какой-либо сертифицированный / стандартизованный / рекомендованный алгоритм.
Ну, я хотел использовать криптографию с открытым ключом, создать пару ключей на основе пароля (обычно для ключей нужно определенное количество случайных байт, я бы вместо них брал SHA2(password)). Тогда сервер бы хранил открытый ключ, клиент шифровал бы scramble, сервер бы его расшифровывал и сравнивал.

Ключи на основе эллиптических кривых намного меньше — так что их удобнее хранить.

Я полез в OpenSSH смотреть, как там создаются ключи, и нашел ed25519. Четыре готовые реализации, public domain, бери, не хочу, уважаемый автор, не абы кто. Аккуратная реализация с защитой от side attacks (а это весьма нетривиально). Опять же, для OpenSSH он достаточно хорош и там он как раз рекомендованный.

И, кстати, все равно SHA512 первым шагом делается, а это уже вполне себе стандартизованный алгоритм.

Новый плагин, как я понимаю, сейчас не просто достаточно, а избыточно безопасен. Сейчас основные проблемы безопасности клиент-серверного протокола находятся в тех его областях, которые аутентификационным плагином не покрываются. В комментах выше, вон, это подробно обсуждалось. Так что нет смысла делать плагин еще безопаснее, защищеннее, ну или сертифицированней. Надо сперва остальной протокол до этого уровня подтянуть.
А что вы думаете о возможности замены / использования криптоалгоритмов на современные Российские ГОСТы, в частности ГОСТ 34.11-2012 для хэша и ГОСТ Р 34.10-2012 для подписи? Да и блочного шифра ГОСТ 34.12-2015?

Алгоритмы есть в свободном доступе, они сертифицированы, по ним работает, например вся банковская система России, доверие к ним есть.
Ну, я выше уже сказал, что я думаю. Что ed25519 уже избыточно безопасен, нет смысла его улучшать еще больше. Надо сперва остальной протокол укреплять.

Но если кто захочет аутентификацию с ГОСТовскими алгоритмами — это несложно. Если есть готовая библиотека с подходящей лицензией, то плагин можно за час-два написать. Вот, например, https://github.com/MariaDB/server/blob/10.1/plugin/auth_ed25519/server_ed25519.c — там просто все.
В предлагаемой вами схеме все таки есть уязвимость и она в следующем.

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

Пример 1. Хакер Али, сделал себе пароль «qwerty», получил хэш «0xAABB», дальше он крадет таблицу с открытыми ключами пользователей и ищет строки «0xAABB». Дальше думаю понятно

Пример 2. Хакер Зина, украла таблицу с открытыми ключами. У нее есть pre-computed таблицы (например, rainbow table) вида пароль-открытый ключ, где вместо хэш функции используется функция получения открытого ключа по хэшу. Дальше классическая атака через pre-computed таблицы.

Пример 3. Хакер Джэк является MiTM. При авторизации он подменяет scramble идущий от сервера на свой. У Джека есть pre-computed таблица вида свой свой исходный пароль — подписанный scrumble. Дальше аналогично (2).

Таким образом фундаментальной проблемой схемы является генерация ключей на базе «чистых паролей пользователей». Для ее устранения подобных проблем в схему нужно добавлять случайность — соль для каждого пароля.
Ну конечно. Я же в конце написал, что брутить пароли можно. Соль добавляет один round-trip, поэтому пока что мы пытаемся обойтись без нее. И так уже три пакета на аутентификацию уходит, с солью будет пять. А в идеале хотелось бы ноль (то есть аутентификация, конечно, есть, но вот overhead-а от нее нет).

Последний пример, с заранее подписанными скрамблами — это интересно. Можно как часть скрамбла время передавать и проверять на клиенте, чтоб не сильно отличалось. Тогда, правда, надо будет часы синхронизировать…
С точки зрения дизайна в чем проблема добавить round-trip?

На сколько я понимаю, авторизация происходит один раз, при установки сессии при этом если у вас будут 2 пакета или 10 пользователь разницы не заметит.

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

С другой стороны, помогая «криворуким» программистам вы закладываете в систему проблемы безопасности которые отразятся на всех пользователях.

На практике, проводя аудит безопасности систем, когда открываешь табличку с паролями пользователей и видишь что у половины из них одинаковые коды паролей (хэши) испытываешь смешанные чувства… причем, для самого распространённого пароля — «1» можно даже визуально запомнить хэш.

Хочу отметить, что взлом через радужные таблицы это все таки не brute force.
Радужные таблицы mixaplhanumeric1-12 дадут злоумышленикам очень хорошие результаты по взлому любых систем построенных по аналогичной схеме вообще. Причем атака будет проводиться практически в режиме реального времени и для этого могут использоваться облачные сервисы, фактически похачить можно с мобильника.
Вы ничего не улучшили, даже ухудшили. Раньше надо было хэш + скрамбл тащить, теперь достаточно лишь «публичных ключей», которые, по сути — те же хэши. Отличная работа
публичного ключа недостаточно для аутентификации. публичного ключа + скрамбла — тоже не достаточно. Нужен секретный ключ. Или брут-форс, но он всегда помогал, тут ничего нового.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории