Привет, Хабр! Меня зовут Ахмадеев Ринат, я Sr. PHP developer.
Представляю вашему вниманию конспект доклада Make passwords great again! Как победить брутфорс и оставить хакеров ни с чем от Алексея Ермишкина из Virgil Security с HighLoad++ 2018.
Когда я шел на доклад, то был настроен пессимистично. Но т.к. это Virgil Security, то я все же решил сходить. В начале доклад казался действительно капитанским, и я даже начал терять интерес, но потом, как оказалось, даже узнал несколько новых подходов защиты паролей, отличных от обычного хеширования с солью.
В докладе рассматриваются способы защиты паролей начиная от хешей и заканчивая более современными подходами, такими как Facebook's password Onion, Sphinx и Pythia. В самом конце рассматривается новый Simple Password-Hardened Encryption Services (PHE).
Мне так понравился доклад, что я подготовил конспект. Всем рекомендую к ознакомлению.
Алексей Ермишкин поделился слайдами и видео доклада в комментариях:
Конспект
Вступление
Всем здравствуйте, всем доброе утро! Я рад всех вас видеть на конференции Highload. Меня зовут Алексей Ермишкин, я работаю в компании Virgil Security.
Мы занимаемся разработкой различных криптографических продуктов как для индивидуальных разработчиков, так и для бизнеса. Фокусируемся на end-to-end решениях, это когда вам не нужно доверять сервису для того что бы выполнять какие-то действия как передача данных, аутентификация, и т.д. Наши SDK открыты и доступны всем для использования.
Издавна пароли использовались как средство аутентификации, как способ куда-то попасть. Это было за долго до того как появились компьютеры. Но с появлением компьютеров, с появлением IT-систем люди не отказались от привычки использовать пароли. Это стало очень большой проблемой для разработчиков, потому что они столкнулись с проблемой как сделать системы одновременно и удобными и быстрыми и защищенными. Очень часто когда какие-то два из этих аспектов пытаются сделать хорошо третий получается не очень. Если вы делаете систему производительной и защищенной то она может быть неудобной и т.д.
Итак, о чем же мы сегодня с вами поговорим?
Я буду рассказывать о защите от offline-атак. Когда пароли попадают в ваши БД, после этого пользователь их не контролирует. Если вашу базу данных взломают, она куда-то утечет, то после этого хакеры могут сделать с ней что угодно. Даже если вы как-то пароли защитили, они могут начать их перебирать и им для этого не нужно ни с кем взаимодействовать, у них для этого уже все есть. Так же пользователи не перестают пользоваться слабыми паролями. Политики паролей конечно вещь полезная, но тоже не всегда удобная, т.е. когда даже люди вводят кажется сильный пароль, политика все равно говорит надо добавить букву или цифру, то для них это не удобно. Так же очевидно, что проблемой является необходимость сравнения того что ввел пользователь с тем что у вас лежит в базе. Как это сделать безопасным образом? Ну и не будем забывать, что внутри компании тоже бывают люди, которые не совсем доброжелательные и хотелось бы защититься так же и от них.
Хеши
В принципе, почему пароли это такая больная тема, почему с ними стоит работать более аккуратно? Проблема в том, что у пароля маленькая энтропия. Что такое энтропия? Это кол-во информации, которая содержится в данных, т.е. например в слове Highload 8 букв — 8 байт, но если мы посчитаем энтропию, оно будет не 64 бита как все слово, а меньше 30-и бит. Когда сегодня говорят о взломе пароля, говорят что можно за такое-то время взломать пароли с энтропией не больше там или не меньше стольких-то бит. Т.е. даже само кол-во паролей не учитывается.
Как же люди начали с безопасностью паролей работать? Первое что пришло в голову — это использовать однонаправленные криптографические хеши.
Их замечательная особенность в том, что их нельзя повернуть назад. Т.е. Если вы в этот хеш передали какую-то информацию, получили на выходе значение, из этого значения обратно эту информацию вы получить не можете. Но, к сожалению, они очень быстро вычисляются. Например, современный кластер из 4-х видеокарт NVidia может перебирать несколько миллиардов паролей в секунду. Т.е. если энтропия вашего пароля меньше 40 бит, то кластер из 4-х видеокарт подберет его там за минуту, а то и того меньше.
Радужные таблицы
К тому же на каждый хитрый хеш найдется своя радужная таблица. Что это за таблица и как их делают?
Т.е. берут самые популярные пароли и комбинации символов, которые могут поместиться на жестком диске, считают для них хеши и кладут их на какое-то больше хранилище несколько терабайт. Когда встречается какой-то хеш его можно не вычислять, а очень быстрой найти по этим таблицам и сопоставить с паролем, который заранее вычислен. Т.е. плюсы таблиц в том что они очень быстро работают, но нужно очень много места для их хранения. Тем не менее для самых популярных хешей таблицы в интернете есть, их можно скачать, или даже купить.
Примечание автора конспекта: Википедия с докладчиком не согласна: "Радужная таблица — специальный вариант таблиц поиска для обращения криптографических хеш-функций, использующий механизм разумного компромисса между временем поиска по таблице и занимаемой памятью." Т.е. там хранятся не хеши самых популярных паролей, которые поместятся на диске, а просто хеши каких-то паролей, остальные же вычисляются на основе тех, что есть — на одну запись в таблице приходится несколько паролей.
Соль
Но опять же на каждую радужную таблицу найдется своя соль. Что такое соль? Это случайный набор байт, который дописывается к паролю. Хранится он в таблице где-то рядом с хешем и защищает от радужных таблиц.
Т.е. людям, которые получили к себе в руки базу с посоленными хешами, все равно придется эти хеши вычислять. Но проблема в том, что вычисляются эти хеши очень быстро и соль тут особо не помогает.
Как замедлить перебор?
Естественным выходом отсюда может стать замедление перебора хешей каким-то образом. Как это можно сделать?
Самый наивный подход это мы берем какую-то функцию хеширования, например sha256 и вычисляем ее итеративно, т.е. вычисляем хеш, от этого хеша еще раз хеш и т.д. Можно делать это много тысяч и даже миллионов раз. Проблема в том, что если вы напишите сами такую реализацию, то она будет скорее всего медленнее чем реализация людей, которые профессионально занимаются перебором паролей.
И поэтому криптографы придумали несколько функций, которые специально созданы для того что бы замедлять перебор паролей — они используют большое количество памяти и все возможные современные инструкции процессора. Если пароль защищенный такой функцией попадет в руки злоумышленников, то им придется использовать очень мощное железо.
К примеру самая современная функция Argon2 работает следующим образом: на схеме можно видеть, что есть очень много различных блоков памяти по которым пробегается хеш. Он это делает различными способами туда-обратно, память используется очень интенсивно, память используется вся. Оптимизировать такую функцию (скорость перебора) довольно сложно.
Но у этих подходов тоже есть свои минусы. Эти функции сделаны медленными специально, но они специально медленные не только у злоумышленников, они специально будут медленными и у вас. Они будут нагружать ваше железо. Эти функции настраиваемые, т.е. можно выбрать какое количество памяти будет использоваться для вычисления хеша одного пароля, вплоть до нескольких гигабайт, сколько делать проходов по этой памяти. Если накрутить эти параметры очень серьезно, то ваше собственное железо будет страдать и если у вас много людей заходит в систему, то вам придется просто под защиту паролей выделять довольно существенные ресурсы и к тому же простые пароли, ну совсем простые пароли все равно могут быть подобраны.
Facebook's password Onion
Люди задумались над этим и задали вопрос можно ли добиться этих же свойств не нагружая бэкенд, не нагружая собственные сервера?
Одним из первопроходцев в этом был Facebook. Эти строчки, которые вы видите, это исторические этапы Facebook, того как они защищали пароли, сначала были просто пароли, потом они взяли старую функцию md5, которая была уже давно взломана, затем они добавили туда соль и взяли хеш sha1, а затем произошла очень интересная штука, они вынесли вычисление функции hmac (это хеш с ключом) на удаленный сервис.
Как это работает? Есть бэкенд, есть удаленный сервис. На этом сервисе есть какой-то секретный ключ. На бэкенд заходит человек, вводит свой пароль. Этот пароль смешивается с солью, которая лежит в базе, прогоняется через хеш и отправляется на сервис. Сервис берет свой секретный ключ, вычисляет функцию hmac и отправляет это все обратно. На бэкенде оно кладется в базу.
Что это дает? Если у Facebook сопрут базу пользователей, то перебирать пароли в ней смысла никакого нет, потому что у них нет удаленного секретного ключа. Но проблема подхода Facebook в том, если что-то случится с их удаленным секретным ключом, то они окажутся в большой беде. Они не смогут ничего с этим сделать, потому что используют хеши, используют hmac. У них нет способов как-то эту ситуацию разрулить так, что бы пользователи ничего не заметили и они этим загнали себя собственно в угол.
Sphinx
Криптографы на все это дело посмотрели. Им идея использования удаленных сервисов понравилась и они решили подумать: можно ли сделать еще лучше? Можно ли сделать похожую систему, но без минусов, которыми ее наделил Facebook?
И решили подойти следующим образом к этой проблеме: что если пароль или хеш от пароля представить в виде числа? Если у нас есть слово passw0rd
, оно состоит из 8-ми байт. Во всех почти языках программирования есть целочисленные типы восьми байтовые, т.е. в принципе это одно и то же. Т.е. 8 байт, слово passw0rd
и мы можем представить его в виде обычного десятичного числа. Что это нам дает? Это нам дает совершенно иную свободу действий. Мы можем пароли или хеши от них складывать, умножать, превращать в какие-то другие числа. Мы можем выполнять с ними настоящие серьезные математические операции.
Одна из первых систем которая использовала эту технологию это Sphinx. Она появилась пару лет назад. Это детерминированный менеджер паролей. Есть много разных программ типа keepass, где у вас есть master-пароль и для каждого сайта он генерирует случайный. Но так же есть детерминированные такие вещи, где вы вводите свой мастер-пароль, сайт, на который хотите зайти и он там что-то вычисляет и выдает уникальный пароль для каждого сайта. Но понятно, если этот мастер пароль куда-то уйдет, то все пароли от ваших сайтов будут навсегда скомпрометированы.
Как подошел к этой проблеме Sphinx? Он берет мастер пароль, он берет домен, на который вы хотите зайти, прогоняет все это дело через хеш и превращает в число. А на самом деле там используется эллиптическая криптография, для простоты я буду все это объяснять на обычных числах с обычной математикой. Он превращает это в число (назовем его a
) и что же он делает дальше?
Совершенно замечательная вещь, мы каждый раз можем генерировать большое случайное число r
. Если возведем число a
в степень r
, а когда-то потом возведем это число в степень обратную числу r
, то мы получим обратно это же число a
, да? Т.е. мы можем с начала замаскировать что-то, а потом демаскировать.
И что делает сфинкс? Опять же есть пользователь, есть удаленный сервис. На этот удаленный сервис отправляется замаскированное число. На удаленном сервисе и есть приватный ключ b
. Что он делает? Он присланное число a^r
домножает на свой секретный ключ b
и отправляет обратно. (Примечание автора конспекта: на слайде присланное число не домножается на приватный ключ, а возводится в степень приватного ключа, но тут главное суть). По скольку число r
каждый раз разное, то удаленный сервис ничего не может сказать о том, какой пароль и домен были замаскированы, т.е. он каждый раз видит какие-то разные случайные числа. И он домножает просто на свой приватный ключ b
и отправляет обратно.
Пользователь демаскирует то, что прислал ему сервер и у него получается число — его мастер пароль с доменом умноженный на секретный ключ сервера a^b
. Получается секретный ключ сервера он не знает, сервер не знает то, что ему прислал пользователь, но в итоге у него получается тоже какое-то детерминированное число. Каждый раз выполняя этот протокол маскировка будет разная, но результат будет всегда одинаковый и этот результат можно будет потом превратить обратно в какой-то пароль и использовать для входа на различные сайты.
По истине замечательная технология. Во первых можно генерировать большие пароли, т.е. она защищает от перебора. Во вторых если хакер получит доступ к нескольким паролям, он ничего не сможет сказать об остальных, т.к. они генерируются независимо друг от друга. В третьих, если у пользователя уплывет куда-то его мастер пароль, то это тоже ничего не даст, потому что у хакеров не будет секретного ключа. В четвертых это работает очень быстро, т.к. здесь не нужно никаких итеративных больших хеширований, т.е. выполняется буквально 2-3 умножения и все работает мгновенно.
Но у этой системы есть и минусы. Сервер, с которым общается пользователь, ничего о нем не знает. Он просто получает на вход какие-то случайные числа, на что-то их умножает и отправляет обратно. Клиент так же ничего не знает о сервере, он куда-то что-то отправляет, получает результат, работает — хорошо. Но если с сервисом что-то случится, то пользователь ничего не сможет об этом сказать, у него нет для этого информации. Секретный ключ так же нельзя поменять, с ним нельзя ничего сделать.
Pythia
А можно лучше?
На эту систему посмотрели криптографы и подумали, а можно ли систему еще усовершенствовать и дополнить ее свойствами, которые бы позволили сказать о том что она соответствует принципам end-to-end? Т.е. клиент может общаться с сервером, но при этом он так же может его аутентифицировать и может ему в какой-то степени доверять.
И придумали такой протокол, который называется Pythia.
Его сделал замечательный человек Adam Everspaugh со своими коллегами. Чем он уникален? Во первых сервис знает, кто вводит пароль, т.е. на сервер по мимо пароля передается идентификатор пользователя. Это может быть какая-то случайная id-шка, которая лежит рядом с ним, или просто user name. Не важно. Но сервис об этом знает. Но мало этого сервер не просто знает, он может строго математически доказать, что он это он.
Как это работает? Есть бэкенд (какой-то веб сервис, сайт) и есть сервис Pythia. Что делает бэкенд и что делает сервис? На сервисе есть приватный ключ k
, но на бэкенд он так же передает свой публичный ключ. Бэкенд на сервис отправляет не только замаскированное число a^r
, как в протоколе Sphinx, но так же отправляет какой-то идентификатор пользователя (UserID
). Сервис домножает идентификатор пользователя и пароль на свой секретный ключ и результат (UserID, a)^(r*k)
отправляет бэкенду. Так же он отправляет в ответ некий Proof
, который может использоваться бэкендом для проверки сервера, что его не взломали, что он отвечает так как должен.
Затем происходит демаскировка и число y
которое получается в итоге кладется в БД. В базе данных у нас лежит не просто какой-то хеш, а лежит число, точка эллиптической кривой.
Здесь есть несколько интересных моментов:
- Возможность для сервера комбинировать пользовательский идентификатор и пароль в одно число. Называется это билинейная операция или билинейное спаривание. Это сравнительно новая математика, которую не так давно начали использовать. У нее есть все свойства новых математик в том что не прошло еще 30и лет для того, что бы все убедились в том что все с этим нормально.
- Зато
Proof
, который отправляет сервис — это довольно старая технология. Это называется протокол Шнорра. Генерация публичного ключа — это умножение базовой точки на какой-то секретный ключ. Протокол Шнорра доказывает, что тот секретный ключ, который использовался для генерации публичного ключа, вот он же и использовался для того что бы умножить пароль пользователя тоже на это же самое число. Этот протокол уже давным давно есть, он используется много где и он позволяет доказать. Это называется доказательство с нулевым разглашением — сервер свой публичный ключ не показывает, но при этом говорит, что ту операцию которую я выполнил, она была произведена именно тем приватным ключом, о котором мы изначально договаривались.
Какие у этой системы есть плюсы?
А их у нее не много.
- Система не нагружает бэкенд. Потому что бэкенд все что делает — это превращает пароль в число, маскирует его, отправляет, потом демаскирует так же результат.
- Если базу с такими числами у вас украдут, то перебирать пароли тоже смысла никакого нет без приватного ключа.
- Сервис Pythia может блокировать попытки перебора, а значит бэкенду этим в принципе не надо заниматься. Если он видит, что под одним и тем же идентификатором пользователя пытаются выполнить эту операцию трансформации несколько раз, он может просто по rate лимиту это все отсечь и заблокировать.
- Благодаря маскировке сервис ничего не знает о пароле. Каждый раз ему присылается новое какое-то случайное число. Константой остается только идентификатор пользователя.
- Благодаря ZKP (Zero-knowledge proof) бэкенд всегда знает, что ему ответил именно тот самый сервис, к которому он когда-то изначально обратился.
- Если у вас есть база с хешами и с солью например, то вы можете мигрировать на такое решение бесшовно для пользователей. Они даже могут ничего не заметить. Вы вместо пароля пользователя берете его хеш, загоняете его в Pythia и в дальнейшем просто используете этот протокол, получаете число
y
, кладете опять его в свою базу. Хеш после этого можно удалить. Каждый раз когда пользователь будет заходить в вашу систему, будет выполняться этот протокол, будет получаться в результате какое-то число, которое вы сравните с тем, что в базе. Собственно система аутентификации останется неизменной, т.к. пользователи будут как логинились раньше, так и логиниться, с теми же самыми паролями, даже слабыми. При этом система будет гораздо более защищенной.
Но это не все плюшки.
Одной из главных фич является то, что даже если взломают сам сервис Pythia, то можно сгенерировать новый приватный ключ. У нас же в базе хранится число, а не хеш. Если мы представим старый ключ как число k
, а новый как число k'
, то мы можем вычислить число, которое называется Update token. Для этого мы умножаем новое число на число обратное старому. И вот этим вот update токеном можно пройтись по базе по каждому пользователю и умножить это число y
на update token. После того, как вы это сделали, у вас система продолжает работать уже с новым приватным ключом на удаленном сервисе. Это все происходит мгновенно. Если случилась беда, у вас украли вашу базу данных с паролями, вы по щелчку пальца выпускаете update token и то, что украли у вас хакеры, становится мгновенно бесполезным. Вы просто потихонечку у себя проходитесь в фоновом режиме по всем записям, обновляете их и у вас они работают с новым секретным ключом. Пользователи вообще даже ничего не замечают. Т.е. бесшовное обновление и мгновенная инвалидация базы паролей, это вот одни из ключевых инновационных функций этой системы.
Но и это еще не все.
Число, которое лежит в базе, большое y
, оно в принципе большое и выглядит довольно псевдослучайно, т.е. его так просто не подобрать. Если мы вот тот функционал, который у нас есть на бэкенде, перенесем, например, на клиентские устройства, на телефоны, то мы можем использовать вот этот y
для генерации ключей. Мы называли эту штуку BrainKey. Значит, пользователь вводит пароль у себя где-то на телефоне, так же его маскирует, отправляет на удаленный сервис. Сервис возвращает ему какое-то число y
и можно потом этот y
использовать для генерации уже каких-то асимметричных ключей. Таким образом пользователь из своего пароля может получить ключевую пару. Это используется во всяких BrainWallet-ах. Это когда вы вводите пароль и получаете сгенерированный для него биткоин кошелек. Но не только криптовалютами ограничивается это применение, это и цифровая подпись, и какие-то бэкапы, и восстановление аккаунта, т.е. везде, где используется асимметричная криптография, где нужны асимметричные ключи. Все это можно использовать, но при этом ключевая пара, а их, в зависимости от необходимости, можно генерировать сколько угодно. Значит они все будут зависеть от пароля пользователя, и это очень удобно.
В бочке меда как бы не без ложечки дегтя.
И особенности этой технологии в том, что она очень новая. В ней используется эллиптическая кривая, которая для билинейных операций (BLS12-381). Сама математика уже существует некоторое время, но вот эта конкретно кривая, которая используется в частности в нашей имплементации, она кроме нас используется только в
PHE
Но мы задумались о том, можно ли сделать еще лучше? Можно ли добиться тех свойств, которые предоставляет Pythia, используя математику как бы вчерашнего дня? Не завтрашнего, не сегодняшнего, а даже вчерашнего, которая используется много лет.
И буквально в июле этого года ученые выпустили новый протокол, который называется Simple Password-Hardened Encryption Services или сокращенно PHE.
Это Russell Lai, ученый из Европы.
В чем преимущество этого сервиса? Во первых он использует стандартную кривую P-256, которая используется везде, во всех браузерах, продуктах, везде кривая по-умолчанию, которой уже много лет. Во вторых эта штука работает примерно раз в 10 быстрее чем Pythia и использует стандартные примитивы. Её как бы сложно, но можно имплементировать собственными руками, не используя какие-то библиотеки непонятные. Можно использовать OpenSSL, или Bouncy Castle, что угодно.
Но работает она немножко по другому. Опять же есть бэкенд, есть сервис PHE. На бэкенде есть публичный ключ, на сервисе есть приватный ключ y
. В отличии от Pythia, процесс регистрации и процесс проверки пароля проходит немножко по-разному. Когда на сервис приходит новый пользователь и хочет зарегистрироваться, что делает бэкенд? С начала он спрашивает у PHE-сервиса дай мне пожалуйста некоторые данные, которые я могу использовать для регистрации, какую-то Enrollment-запись. Сервис говорит OK и отвечает бэкенду следующими штуками. Он генерирует некую случайную 32-х байтную соль (sNonce
). На основе этой соли и своего приватного ключа y он генерирует два числа, назовем их C0
и C1
. Так же он генерирует доказательства (Proof
) того что эти два числа или там 2 точки были сгенерированы именно с использованием его приватного ключа y
, используя протокол Шнорра (как в предыдущих протоколах). Бэкенд проверяет Proof
. Пароля здесь пока еще нет. Что делает бэкенд? У него со своей стороны тоже есть свой личный клиентский приватный ключ x
и он, получив пароль от пользователя, делает примерно те же самое что делал сервис, только добавляет туда еще пароль. Он берет случайный cNonce
(случайную клиентскую соль), пароль и генерирует опять 2 числа HC0
и HC1
. Зачем 2? Потому что первое HC0
используется для аутентификации, а во второе число HC1
у нас подмешивается еще некое случайное число M
домноженное на приватный ключ x
(MC
). Число M
размером тоже 32 байта и в последствии может использоваться для шифрования пользовательских данных (у нас же Encryption Services) (примечание автора конспекта: ключ шифрования в данном случае будет MC
). Число MC
будет доступно в качестве ключа только после того, как пользователь ввел правильный пароль. Получается на этапе регистрации вы можете сгенерировать не только запись для авторизации, но и ключ шифрования, уникальный для каждого пользователя, которым можно зашифровать его профиль, какие-то данные, еще что-то. Затем бэкенд просто складывает то что прислал сервис и то что сделал он — складывает эти точки и получает T0
и T1
. В первом случае складывает две (C0 + HC0
), а во втором три (C1 + HC1 + MC
). И кладет в базу 2 соли (sNonce
, cNonce
), с помощью которых были получены эти числа и 2 числа (T0
и T1
), которые получились в результате суммы.
Соответственно процесс аутентификации пользователя происходит в обратном порядке. Пользователь вводит свой пароль на бэкенде. Бэкенд вычисляет HC0
и из того, что у него лежит в базе, вычитает HC0
из T0
и отправляет получившееся C0
на сервис вместе с серверной солью. Сервис, зная серверную соль, вычисляет у себя эту же самую точку и смотрит, она совпадает с тем что прислал бэкенд или нет, если она совпадает, то значит пароль верный и можно ответить ему вторым числом C1
, которое он вычтет вместе с HC1
из числа T1
и получит ключ шифрования. Таким образом пароль на сервис PHE даже не уходит. Он даже не покидает бэкенд. Он в виде каких-то точек умноженных на приватный ключ бэкенда. Он даже не существует как таковой, но при этом удаленный сервис может сделать строгий вывод о том корректный или нет этот пароль и доказать еще по мимо этого то, что он все вычисления провел с помощью своего приватного ключа y
.
Какие у этой системы есть особенности?
Пароль как я уже говорил не покидает бэкенд. Но в отличии от Pythia нужен приватный ключ на бэкенде. Ну нужен и нужен, сохраним куда-нибудь. PHE обладает всеми основными функциями Pythia:
- можно так же выпустить update token если у вас что-то случилось с приватным ключом;
- можно так же пройтись по всей базе, обновить и все будет как и было;
- защита от перебора;
- сервис ничего не знает о пароле;
- строгие доказательства (Pythia вот, кстати, не знает, пароль правильный не правильный, а PHE знает);
- возможность обновлять базу и ключи.
И нам так понравилась эта штука...
… что мы взяли и запилили сервис. Буквально вот ребята ночью его доделывали. Называется он passw0rd.io с ноликом. Во первых слово password с ноликом, это вот самый 18-й по популярности пароль в мире среди всех паролей, во вторых нолик символизирует, то что это zero trust, т.е. сервису можно не доверять. Так же это бесплатный сервис, абсолютно, т.е. как Let's encrypt. Можно прийти, зарегистрироваться и пользоваться. У него есть CLI для основных операций для регистрации, для создания приложений. Мы на сегодняшний день успели выпустить 2 SDK, это GO и .Net, которые работают с этим сервисом.
Ну и напоследок хочется сказать что пароли это как нижнее белье:
- Стоит их регулярно менять.
- Не стоит их оставлять на столе.
- Не надо их никому отдавать.
На этом у меня все, я благодарю вас за внимание и спасибо за то что пришли на доклад.
ВОПРОСЫ?
Слайд 37. ВОПРОСЫ?
Возможно у вас есть вопросы.
Q: Здравствуйте, большое спасибо за доклад! Такой небольшой вопрос. Если у нас есть злоумышленник, который получил доступ к сервису Pythia и используя те данные выпустит свой update token, то у нас не потеряются абсолютно все пароли? Потому что мы не будем знать какой private key он использовал. Сможем ли мы их восстановить используя еще один update token? Или нет?
A: Да, update token-ы можно обновлять сколько угодно раз.
Q: Тогда собственно другой вопрос. Если этот злоумышленник остается с каким-то снифером в нашей сети и слушает новые update token-ы, то он может бесконечно обновлять свой Private key и мы никогда не сможем защитить от него базу?
A: Нет, ну процесс выпуска update token-ов, он как бы не автоматический, если что-то случается, происходит нотификация всех, нас взломали, мы будем выпускать update token. И если это сделает злоумышленник, т.е. разошлет всем почту.
Q: Нет, спасибо, если он не автоматически, то все понятно.
A: Т.е. тут есть возможность ручного управления.
Q: Здравствуйте, у меня вопрос, там вы говорили бесшовно мигрировать, если у вас используется какой-то хеш в Pythia и что-то я не очень понимаю, если у нас есть миллион сессий активных, соответственно бэкенд не знает пароли, мы можем бесшовно?
A: Да конечно.
Q: Мы заставим их заново вводить пароли?
A: Нет, мы просто вместо паролей в Pythia будем передавать хеш. Т.е. вы оставляете у себя соль, но когда пользователь логинится вы вычисляете опять хеш.
Q: (Не разборчиво) Так bcrypt все равно придется вычислять на бэкенде?
A: Хеш, который был у вас в базе, его придется вычислять, ну это не абы какая сложность.
Q: Доброе утро, у меня фанские вопросы. Какой пароль самый популярный все таки? Раз тот, который…
A: password без нуля
Q: password без нуля? Огонь! Вообще.
A: 123456 еще вот тоже, там в зависимости от года они там 12345, 123456.
Q: Хорошо. И вот минусы Pythia были отмечены, минусы PHE я не увидел.
A: А мы не нашли, мы собственно по этому как бы и закончили на этом доклад.
Q: Понятно. И третий вопрос. Вот сейчас кроме вас кто вообще использует такие штуки? В production для своих сервисов?
A: Никто пока. А! Яндекс использует Pythia.
Q: Яндекс использует Pythia, а он для чего, известно?
A: Для паролей.
Q: В каких сервисах, во всех?
A: Понятия не имею.
Q: Ок, понятно, спасибо!
A: Но они не выпустили SDK, и не показали это никому.
Q: Здравствуйте, вот скажите, вы говорили, что исключается возможность подбора пароля, т.е. там настраивается какое-то количество попыток, после которого замедляется подбор паролей? И сервис что делает? Перестает отвечать или как?
A: Нет, ну это настраивается же, в зависимости от потребности, т.е. сейчас у нас например на сервисе PHE, который мы недавно подняли, там то ли 5 паролей в 2 секунды, то ли 2 пароля в 5 секунд можно. Главное преимущество в том, что вы можете регулировать это. Можно например для PHE (он знает, что пароль ввели неправильно), если ввели неправильный пароль, то сделать блок на 10 секунд, или там на минуту.
Q: Т.е. вы помимо этого еще используете какие-то метрики, что бы словить алерты и какие-то действия предпринимать? Подразумевается ли такое?
A: Это можно сделать. Сейчас пока сделан просто rate limiting, а в принципе, в дальнейшем мы внедрим туда политики и вы сами сможете настраивать как реагировать на эти события.
Q: Т.е. момент подбора пароля к разным аккаунтам или к одному будет обнаружен таким образом, да?
A: Да.
Q: Здравствуйте. Подскажите, т.е. в итоге если украдут ключ с Pythia и украдут вашу базу паролей (хешей), то пароли я так понимаю все равно можно будет забрутфорсить, да? Подобрать?
A: Да, но проблема в том, что это надо сделать одновременно.
Q: До того, как выйдет update на вашу базу?
A: Да, если мы рассматриваем Pythia как сервис, который не стоит у вас же в вашей инфраструктуре, а какой-то другой удаленный сервис в какой-то другой компании, например у нас, то нужно будет взломать одновременно вас и нас, ну это как бы удачи)
A: Все? Спасибо всем большое! Надеюсь вам понравилось. У нас еще есть квест, кстати, на тему PHE, можно побрутфорсить хеши, приходите.
Выводы
На мой взгляд у сервиса PHE (как и у остальных сервисов) все же есть минус по сравнению с классическим подходом хеш+соль — добавляются точки отказа (сеть до сервиса, сервер с сервисом, сам сервис) и скорость выполнения операции увеличивается (как минимум за счет сетевого взаимодействия). Если использовать PHE сторонней компании как совершенно внешний сервис, то сюда добавляется еще сеть между датацентрами как точка отказа и дополнительное время на установление соединения и пересылку байтиков.
Тем не менее плюсы все же выглядят довольно вкусно:
- перебирать пароли как заверяют будет невозможно (или очень долго) без приватных ключей;
- в случае утечки базы или ключа достаточно обновить ключ и данные в базе (при должном умении это можно сделать бесшовно).
В общем, технология выглядит перспективно и я продолжу наблюдать за ней.
Спасибо Алексею Ермишкину Scratch и компании Virgil Security за то, что исследуете эту тему, делитесь информацией и публикуете исходные коды!
А как вы защищаете пароли (если не секрет)?
UPD: Спасибо Алексею Scratch. Он скинул в комментариях ссылки на презентацию и видео доклада. Я добавил их в конспект, а так же приложил слайды. Теперь конспект более читаемый.
Комментарии (28)
Loki3000
10.01.2019 14:33+1A: Да, но проблема в том, что это надо сделать одновременно.
Мне кажется что ребята лукавят: если у одного из клиентов сперли базу, не станут они менять ключи, так как при этом придется апдейтить хэши всем их клиентам. Так что утекшая таблица вполне может лежать и ждать компрометации ключей. Причем, если я правильно понял принцип работы, в случае компрометации ключей хэши даже перебирать не придется — они просто расшифровываются ключом. Разве нет?
PS Справедливости ради, для каждого клиента может быть свой комплект ключей. Тогда проблема решается достаточно просто. Правда, все равно клиент должен быть в курсе что его взломали.mougrim Автор
10.01.2019 14:46Причем, если я правильно понял принцип работы, в случае компрометации ключей хэши даже перебирать не придется — они просто расшифровываются ключом. Разве нет?
Как я понимаю нет. Оно работает в одну сторону, т.е. имея пароль, данные из БД и приватные ключи бэкенда и сервиса можно понять, правильный ли пароль. Но имея данные из БД и приватные ключи бэкенда и сервиса пароль можно только подобрать.
PS Справедливости ради, для каждого клиента может быть свой комплект ключей. Тогда проблема решается достаточно просто.
Не могу сказать за докладчика, но думаю было бы вполне логично для каждого клиента, и даже для каждого приложения клиента иметь свой комплект ключей и в сервисе и на бекэнде.
Правда, все равно клиент должен быть в курсе что его взломали.
Согласен. Здесь наверное поможет профилактика — периодически полностью переустанавливать сервера и обновлять ключи.kowack
11.01.2019 21:31Согласен. Здесь наверное поможет профилактика — периодически полностью переустанавливать сервера и обновлять ключи.
Я не выспался или получается что это практически равносильно вынести туже «соль» на отдельный сервис?mougrim Автор
11.01.2019 21:34+1Если абстрагироваться от деталей, то это действительно похоже на то, что добавляется новая глобальная соль, которая находится на отдельном сервисе. В случае Facebook's password Onion, это было именно так.
Но не равносильно это потому что в случае Pythia и PHE ключ (который вы назвали солью) можно менять не зная ничего о пароле.
Соль поменять нельзя не имея пароля.Scratch
11.01.2019 22:29Все верно. Это чем-то напоминает удалённую соль, которую можно менять без вмешательства пользователя
Scratch
10.01.2019 14:58+4Спасбо за конспект! Слайды тут, если интересно
www.dropbox.com/s/a4fctwy8nzlasao/Make.Passwords.Great.Again.Ermishkin.v3.pdf?dl=0
Можно было стукнуться в личку, я бы помог )
worldmind
10.01.2019 14:59+1Честно говоря не осилил последние схемы работы, думаю нужны sequence диаграммы.
Scratch
xDimaRus
10.01.2019 15:26Про Sphinx: там именно возведение в степень? Что мешает клиенту вычислить логарифм и получить секретный ключ b?
Scratch
10.01.2019 15:58+1Вообще там скалярное умножение в группе точек эллиптической кривой, но я для простоты решил заменить на возведение в степень по модулю. Вот реализация, можете посмотреть gist.github.com/Scratch-net/37ae11e589ea3d17fe104a2630306042
Scratch
10.01.2019 17:55Кстати, вот видос выступления, можно добавить
www.youtube.com/watch?v=y1MQyl13ssc
Nexus7
10.01.2019 18:50В докладе почему-то не упомянут SCRAM (RFC5802 etc.) Он работает на любых стандартных хэшах, без всяких там открытых/закрытых ключей, пароль пользователя никогда не покидает приложение/браузер. Идеологически ближе к Argon2, но долгий расчёт идёт на фронте, бэк делает только минимальные преобразования и ходит в базу. И клиент и сервер друг друга аутенифицируют.
Scratch
10.01.2019 19:17Я не упоминал протоколы, которые требуют работы на клиенте, потому что ну, они требуют работы на клиенте. Если всякие PAKE в приложения еще можно встроить, то в вебе этого никто делать не будет
Nexus7
10.01.2019 19:50Года три с лишним назад самолично внедрил SCRAM-аутентификацию сначала в мобильном приложении, а потом коллеги сделали то же самое на сайте одной большой организации. До этого там передавались пароли по HTTPS почти в открытом виде, они же хранились в базе данных. Протокол SCRAM немного модернизировали так, что клиенты вообще не заметили миграции со старой схемы на новую.
Странно, что на слайде 7 упор делается на то, что длительные/прожорливые функции выполняются на сервере. Чтобы не грузить бэки все долгие расчёты должны быть на клиенте, благо сейчас они все достаточно мощные по памяти и процессорам.
И главное, что нет PKI, которую надо обслуживать.Scratch
10.01.2019 20:37Что значит «почти в открытом виде»? Насколько мне известно, TLS пока не взломан.
Так же при SCRAM сервер отправляет клиенту соль, позволяя выполнить precomputation атаку в случае, если злоумышленник её получит.
Современные решения не страдают этими болячками, но их надо имплементить и на клиентской и на серверной стороне, а делать этого никто не хочетNexus7
10.01.2019 22:19Что значит «почти в открытом виде»?
Они передавали MD5(password), считая это защищённым решением. Эти же данные хранили в базе без всяких солей и нонсов. Как их не взломали за несколько лет работы сайта я не знаю ;)
TLS пока не взломан
Я тоже так думал, пока мне антивирус не написал в отправляемом через gmail.com письме, что оно проверено, вирусов нет. Без пининга сертификата TLS бесполезен, хотя и работает в большинстве случаев. А пининг — это та ещё головная боль.
позволяя выполнить precomputation атаку
Насколько я помню, там с двух сторон передаются случайные нонсы, они помогут от такой атаки?
делать этого никто не хочет
Странное заявление. Если строится продукт (сайт, приложение, а то и всё сразу), то написать 200 строчек кода протокола с его модульными тестами и сколько-то строк доступа к базе данных на бэке — это не большая проблема по сравнению с медиаповодом в стиле «очередная утечка паролей у <тех, кто не хочет>». Хотя да, в большинстве своём архитекторы-аналитики в основном решают бизнес-задачи, им на реальную безопасность компании и клиентов глубоко фиолетово. И начинают шевелится только тогда, когда очередные пенетраторы им показывают список найденного ;)
kuza2000
10.01.2019 20:53Это кол-во информации, которая содержится в данных
Так говорить нельзя. Скорее, наоборот — больше энтропия, меньше информации. То есть, чем более случайный пароль (меньше информации), тем больше будет его энтропия (например, в битах).
Tangeman
11.01.2019 01:59Насколько я понимаю, сервис можно использовать чисто для экспериментов? Потому как отсутствуют какие-либо гарантии (SLA) и уверенность в том что он вдруг резко не станет очень платным и не прекратит существование.
Честно говоря, аутсорсить проверку паролей кому-то совершенно чужому — как-то очень стрёмно, ибо если что — то сервис превращается в тыкву, ничего не работает, пользователи негодуют и всё такое.
В Letsencrypt много кто заинтересован, посему шансы что он умрёт уж очень малы (несмотря на бесплатность), да и альтернативы есть, но тут совсем другое дело.Scratch
11.01.2019 07:26Конечно мы планируем опубликовать SLA после полноценного релиза, но для тех кто переживает всегда есть возможность написать сервис самим и разместить на своих мощностях. Пока что цель — дать людям попробовать протокол, API, собрать отзывы, сделать больше документации, мануалов по миграции и т п.
xDimaRus
Подразумевает ли сказанное что функция аутентификации атакуемой системы должна иметь нулевое время возврата результата и не блокировать атакуемую учётную запись? Или тут опечатка — переберет.
mougrim Автор
Здесь имеется ввиду, что если хакер получит хеш пароля, то он сможет подобрать пароль вычисляя хеши возможных паролей на видеокартах.
Затрудняюсь ответить, есть ли разница между «подберет» и «переберет».
xDimaRus
Если получит то да, разницы нет.