Pull to refresh
33
0
Всеволод Стахов @cebka

Программист, разработчик Rspamd и FreeBSD pkg

Send message
К сожалению, сами регэкспы я не могу показывать, т.к. это внутренние данные компании. Сообщение показать могу — это большое спамерское письмо, повторенное много раз: highsecure.ru/hs_test/text. А для последнего теста (статических строк) я брал фид с publicsuffix.org и чистил его от комментариев.
Я не использую IDE для сборки и дебага — мне хватает для этого gdb — поэтому я вряд ли могу что-то сказать по этому вопросу.
Да, таких случаев у меня получилось аж две штуки в проекте. И каждый, я думаю, надо рефакторить на самом деле.
Не соглашусь с отсутствием пользы. Если бы проект не был opensource, то не было бы сторонних котрибьюторов, не было бы производных проектов — той же libucl, включенной в базу FreeBSD, и, наконец, не было бы чрезвычайно удобных инструментов — github, jenkins, а также, например, Google Summer Of Code, в котором в этом году участвовал rspamd. Более того, открытый код дисциплинирует программиста, так как вся его работа видна без ограничений, а это немаловажный фактор и мотиватор для саморазвития.
Расскажу свою балалайку на тему opensource. В отличие от многих тут отписавшихся людей, моя профессиональная активность была практически с самого начала связана с написанием opensource проектов. Просто на работе (в Рамблер-почте тогда) решили, что нет нужды прятать код, зато можно подчерпнуть много пользы от коммьюнити. Тогда же я начал писать свой основной проект — систему антиспама rspamd. И так вышло, что в отличие от других игроков на рынке, проект пилился силами только одного человека — меня — но зато получал довольно значимый фидбек от других пользователей.

Дальше стали появляться и другие контрибуторы. Конечно, специфика системы фильтрации спама в том, чтобы крупные пользователи составляли собственный уникальный набор правил и нигде его не «светили» по очевидным причинам. Сохранение же базы в виде открытого кода никак не вредит таким пользователям. Со временем я переехал в UK, где на меня примерно год назад вышла местная фирма, которая захотела работать с моей системой и наняла меня на работу. При этом код проекта все равно остается под opensource (BSD) лицензией (что, кстати, является очень нехарактерным для энтерпрайз сектора в UK). Таким образом, мне уже много лет удается совмещать занятие opensource и получать за это зарплату. Если данная тематика интересна, я могу, наверное, попробовать написать более длинную статью о таком применении opensource.
Я в таких случаях применяю комбат-мультиспрей DNSCrypt: dnscrypt.org
Имеется в наличии: довольно удобный (хотя и ужасный внутри) плагин для win/osx, довольно большое число публичных серверов из коробки, возможность установки своего рекурсора с dnscrypt, возможность работы через tcp/443.
Не знаю, что вы так привязались к «закрытым проприетарным» системам. Задача создания безопасных соединений всегда очерчивается моделью угроз. Если вы используете «открытый» ГПСЧ (хотя бы тот же fortuna от FreeBSD), то это все равно не дает гарантий, что вы защищены, скажем, от закладок в оборудовании или чего-то подобного Dual EC DRBG (как видите, открытость все равно не исключает закладок в коде). В таком случае, если мы исключаем collocated adversary из модели угроз, то можно взять хотя бы тот же RDRAND + какие-то шумы от пользователя, скормить их фортуне или же взять тот же PRF на базе чачи. И это будет все равно лучше, чем упорствовать, что работать в закрытых проприетарных системах не может быть безопасным (потому что в вашей модели угроз безопасности все равно не существует).
Еще есть неплохая библиотека от Mike Hamburg для таких операций. Подробнее про нее и практическое применение elligator тут: www.mail-archive.com/curves@moderncrypto.org/msg00412.html
Ну так классические s-блоки были предназначены для реализации в железе, где они просто представляются дешифраторами (и однозначно имеют constant time для любых входных комбинаций). А в софте часто используют «оптимизации» AES на достаточно больших таблицах подстановки. Но даже в таком случае я не вижу абсолютно никакой реальной возможности timing атаки. Если мы берем SMP систему, где есть планировщик задач, прерывания и уж тем более, если мы берем сеть с ее непредсказуемым шумом. «Железный» aes по определеню constant time (те же AES-NI).

Насчет чачи у меня очень противоречивое мнение. С одной стороны, мне нравится реализация алгоритма в софте. С другой же, когда я внимательно смотрел пермутации чачи, мне это показалось очень-очень похожим на классическую s-p сеть, где s блок — это сложение по модулю 32, а p блок — ротации. Но однозначно я могу сказать только то, что глубина криптоанализа aes пока не сравнится с анализом чачи (хотя eSTREAM — это очень уважаемое мероприятие, бесспорно). И наблюдаемые на практике статистические bias'ы мне крайне не понравились:

paste.lisp.org/display/144927

AES-CTR прошел все тесты без проблем. RC4 я не тестировал, скажу сразу :)
Ну, насчет уязвимостей в AES вы загнули, конечно, конкретно. Нет, во влажных мечтаниях Бернштайна, конечно, любой алгоритм с s-блоками подвержен timing attack (если не используются constant time hardware implementation). Но на практике это не было и никогда не будет применимо, особенно по сети. А вот у salsa/chacha выход keystream однозначно более biased, чем выход от AES-CTR, что обнаруживается статистически. Я ненастоящий сварщик, чтобы из этого делать выводы, но и заявлять, что, дескать, chacha безопаснее AES, я бы сильно поостерегся.
Все хорошо, но откуда вы возьмете ключ для MAC'а? Напомню, что poly1305 в данном виде не содержит финального раунда aes и не принимает, соответственно nonce. У HMAC, напомню также, такой проблемы нет — там можно использовать один и тот же ключ сколь угодно долго. Хотя на практике его все равно ротируют, чтобы ограничить время на поиск коллизий.
Ну вот как раз нулей я хотел избежать по причине сложностей с копированием и лишних маркеров для анализаторов (все-таки 16 нулей последовательно нечасто встречаются в реальных данных): github.com/vstakhov/rspamd/blob/master/src/libcryptobox/cryptobox.c#L162

Да, конечно же вторая часть первого блока используется уже для payload. И да, мой подход хуже, если в протоколе много очень коротких сообщений (меньше 32-х байт), т.к. делается дополнительный раунд пермутаций. С другой же стороны, он более скрытный и простой в плане адаптации существующего кода.
Не понимаю, откуда вы предлагаете брать уникальную гамму, если не использовать раунда шифрования.
Дело не столько в производительности, сколько в алгоритмическом усложнении. Допустим, мы зашифровали 256 бит подключа, у нас осталось еще 256 бит ключевого потока. Нужно это как-то сохранить в блоке, а потом начать шифровать вначале куском того keystream, что у нас имеется, а потом уже начинать новый раунд пермутаций. Это существенное усложнение кода, и рефренсная имплементация этого не делает. Более того, nacl Бернштайна и libsodium при определении cryptobox и secretbox из-за этого делают вот эти вот уродливые cryptobox_ZEROBYTES = 32, а cryptobox_BOXZEROBYTES = 16, что делает сущим мучением применение этих примитив на практике. То есть, делается так:

Берется весь поток, в котором первые 32 байта (т.е. полный блок chacha/salsa) забиваются нулями. Дальше прилепляется plaintext. Дальше делается xchacha/xsalsa с заданным ключом на все данные (т.е. 32 байта нулей и весь payload). Потом первые 16 байт используются как ключ для poly1305, а в оставшиеся 16 байт записывается mac от шифротекста без первых 32-х байт. Расшифровка еще хуже: берется 32 байта, зануляются, потом по ним делают полную итерацию xchacha/xsalsa и получают искомые 16 (!) байт ключа для poly1305, потом проверяется целостность шифротекста, а дальше прогоняется полная итерация xchacha/xsalsa по всему payload, а первые 32 уже байта забиваются нулями.

Вот такой вот подход позволил избежать кусковых блоков, но с другой стороны добавил лишние нули в конструкции и постоянно требует копирования шифротекста/плейнтекста, что очень неудобно на практике (и в реализации протоколов).
1,2. Игнорируют из-за того, что размер блока сальсы и чачи 512 байт, а шифровать дробными блоками очень трудно и неудобно (т.е. есть негативный эффект на производительность). Да и reference имплементация и не умеет шифровать дробными блоками на самом деле.

3. curve25519 задается уравнением y^2 = x^3 + 486662*x^2 + x. Публичный ключ — это точка на этой кривой в поле 2^255 − 19. Точек, принадлежащих кривой, на этом поле значительно меньше, чем значений в поле. Но поскольку брутфорс салсы требует примерно 2^256 попыток, то да, коллизий будет очень много. Но если предположить, что есть более эффективный способ взлома PRF, то все хуже.
Да, я сейчас прочитал про EKE, и понял, что был неправ. Просто из вашей статьи не следует полного описания самого EKE и получения на его основе PSK, отчего я решил, что PSK заранее подкладывается клиенту и серверу.
1. Надо делить не биты, а сложность дискретного логарифма, и даже не делить, а брать квадратный корень. Поэтому эти детерминированные биты в приватном ключе по факту не влияют на сложность дискретного логарифма (если вы не собрались, конечно, брутфорсить все 256 бит ключа, тогда да — их надо исключать из сложности такого перебора, но она будет заведомо намного больше, чем 128 бит).

2. Это излишне, если вы применяете hsalsa. Задача атакующего тут в том, чтобы из ключа сервера и собственной ключевой пары подобрать такую пару, чтобы ее умножение давало бы гарантированно слабый ключ для hsalsa. Но это не даст ничего, т.к. выхлоп hsalsa даже со слабым ключом, очевидно, не будет давать слабого ключа для последующих применений salsa (хотя у rc4 есть определенные забавные ключи, да).

3. Передаваемые вами публичные DH ключи — это не шум для внешнего наблюдателя. Если атакующий брутфорсит передаваемые данные, то ему достаточно проверять, лежит ли то, что он получил, на кривой curve25519 (а это делается просто подстановкой данных в уравнение), чтобы понять, правильно ли он расшифровал данные. После чего он получает PSK. Варианты коллизий точек, в принципе, возможны, но все равно мне не кажется, что это zero-proof.
Крайне странный подход. Ведь вам нужно этот psk как-то еще и передать между клиентом и сервером. А в случае пароля достаточно взять PBKDF и применить его клиентом и сервером. Или же вообще взять OTR и их 'Socialist millionaire problem' подход к проверке сторон (который, кстати, действительно является zero-proof протоколом).
Да, еще такой вопрос: откуда вы берете и как передаете PSK в вашей схеме? Ведь я правильно понимаю, что вы генерируете его из пароля (в таком случае вопрос к PRNG становится вообще неясным, для чего нужны вам криптографически стойкие случайные числа).
Немного не понял вашего описания ECDH.

1.
Curve25519 всё же имеет не все 256 бит задействованными, соответственно, его криптографическая стойкость чуть меньше симметричного аналога 128 бит порога.


Вообще, автор curve25519 описывает пороговый уровень безопасности ECDH c этой кривой в 128 бит. Но значение rho для нее, все-таки, 126 бит: safecurves.cr.yp.to/rho.html

2.
Кроме того, не добропорядочная сторона может использовать специально созданные публичные ключи, которые при перемножении могут давать слабые ключи K: в теории такое не исключено, хотя на практике для Curve25519 не замечено.


Традиционный способ ECDH на curve25519 — это генерировать сессионный ключ после одного раунда hsalsa (или hcacha). Например, как это делал я: github.com/vstakhov/rspamd/blob/master/src/libcryptobox/cryptobox.c#L146 (в nacl там hsalsa).

3.
При этом имеется такое свойство, как нулевое неразглашение (zero-knowledge proof), при котором ни бита информации о PSK-ключе не будет известно злоумышленнику: он получает зашифрованные данные (шум) и единственное, что он может предпринять, так это попытаться дешифровать, но у него нет возможности узнать правильно ли он нашёл публичный ключ (дешифровал ли его), так как он тоже является шумом.


Немного не понял, почему вы считаете, что публичный ключ — это шум? На самом деле, публичный ключ — это точка на кривой, и если его не прятать специально (например, elligator'ом), то отличить его от шума элементарно. Ну и определение zero-knowledge proof все-таки неверно в таком случае.

Information

Rating
Does not participate
Location
Cambridge, England - East, Великобритания
Registered
Activity