Ад — это чересчур уверенные в себе разработчики, пишущие собственную криптографию

в 13:01, , рубрики: cryptography, e2ee, openssl, ruvds_перевод, криптография, сквозное шифрование

Ад — это чересчур уверенные в себе разработчики, пишущие собственную криптографию - 1


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

Само по себе это необязательно плохо, несмотря на то, что одна из аксиом информационной безопасности запрещает делать именно это. Написание криптографического кода (но не его развёртывание или публикация!) — важный первый шаг в обучении алгоритмам.

Я заметил такую тенденцию (как в примере с Session): разработчики некорректно утверждают, что не реализуют собственную криптографию, ведь они используют низкоуровневую криптографическую библиотеку.

Эта ошибка свойственна не только сомнительным приложениям, форкающим мессенджеры со сквозным шифрованием, чтобы вырезать прямую секретность (forward secrecy).

Криптография уровня «стартап»

Насладитесь репринтом How we share secrets at a fully-remote startup за январь 2025 года поста за 2024 год о том же криптографическом коде, который изначально пал жертвой Padding Oracle Attack Блейхенбахера 1998 года (наверно, это самая старая ошибка при реальном применении криптографии и одна из причин, по которой профессиональные криптографы советую перестать использовать RSA).

Уточню, что прошу насладиться статьёй не для того, чтобы раскритиковать её автора.

Он далеко не первый, кто реализует собственную криптографию. И даже не первый, кто делает это на этой неделе.

Зато он любезно разобрал свой код и рассказал о том, что же они написали; я думаю, это проливает свет на то, как люди рассуждают о криптографическом коде.

Пост начинается с повторения правила, которое мы постоянно слышим от специалистов по безопасности:

Не реализуйте собственную систему безопасности

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

И это действительно хороший совет!

Но если пролистать пост чуть дальше, то вы увидите и следующее:

Реализовали ли мы собственную систему безопасности?

Едва ли. В нашем решении используется криптографический код из надёжных источников: Node.js, его криптомодуля и библиотеки OpenSSL, на которой он основан. Это уважаемые, качественно поддерживаемые и популярные опенсорсные инструменты, за которыми внимательно наблюдают исследователи безопасности.

Хм, это утверждение чем-то нам знакомо, не так ли?

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

Конкретно этим-то данный пост и интересен для меня.

Описываемый в нём код выглядит именно так, как должен выглядеть код из поста с подобным когнитивным диссонансом:

О, и я ведь ещё не сказал о том, что другие люди пытались отговорить автора от развёртывания собственной реализации ещё в первый раз (то есть полгода назад).

Дополнение к моему посту: автор изменил свой код, теперь RSA используется только для обёртывания ключа, а AES-CBC заменён на AES-GCM.

Это существенное улучшение по сравнению с тем, что они делали раньше. В данном конкретном примере мы дождались хэппи-энда.

Бесчисленное количество нерассказанных историй

Да, мы можем раскритиковать код и пост, но, по крайней мере, разработчики здесь честны и прозрачны.

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

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

К сожалению, все мои лучшие работы выполнялись под NDA. То есть я при всём желании не мог бы привести подробности. Разговоры, которые я вёл в течение долгих лет, могли бы вызвать мурашки у большинства неофитов в сфере информационной безопасности. К счастью, мы с коллегами успешно убеждали разработчиков, что ситуацию нужно менять.

Вот некоторые из ярких примеров:

  • Я видел, как люди использовали md5($password) в качестве функции генерации ключей для libsodium.
  • Я видел, как люди шифровали поля базы данных, а потом сохраняли ключ дешифровки прямо рядом с зашифрованным текстом. Затем они совершали гениальный ход: писали логику дешифровки на SQL, чтобы можно было выполнять запросы к базе данных по зашифрованным полям.
  • Как минимум один раз при анализе проекта со сквозным шифрованием, в котором криптография была реализована на JavaScript и должна была выполняться в веб-браузере, я задавал вопрос: «Откуда вы знаете, какому публичному ключу можно доверять?». Мне ответили что-то вроде: «О, мы просто храним их в MySQL и получаем их с сервера».

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

Перед кустарной криптографией могут не устоять даже крупные технологические компании.

Гордыня побеждает

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

Я считаю, что это явление продолжает существовать по следующей простой причине:

У большинства людей нет фундаментального понимания того, что же такое реализация собственной криптографии.

Их несогласие с этим состоит из нескольких слоёв.

▍ Ошибочно понятые границы

Самое важное значение реализации собственной криптографии заключается в трате любого количества «очков инноваций» на любом уровне абстракций без адекватного обеспечения корректности и/или контроля со стороны специалистов по криптографии (предпочтительно тех, у кого есть хотя бы какой-то опыт во взломе чужих реализаций).

И это касается не только людей наподобие разработчика Crystalline!

То, что вы отдаёте реализации блочного шифрования на аутсорс модулю crypto своего языка программирования, не означает, что вы не реализуете собственное крипто.

Криптография существует не только на примитивном слое. Любые протоколы, использующие криптографию — это тоже крипто! Это радиоактивный и биологически опасный материал.

▍ Что вообще такое «собственная криптография»?

В этой часто повторяемой фразе теряется понятие того, что же такое на самом деле ваша собственная криптография.

Размазывает ли работа в команде ответственность за её наличие?

Только ли в новизне проблема? Разумеется, нет. Если бы всё было так просто, то достаточно было бы придерживаться готовых стандартов.

Так почему же столь многие реализации JSON Web Token совершают ужасные ошибки?

▍ Будут слёзы

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

  • Написание кода UI, обёртывающего libsignal для реализации E2EE — это не что-то новое, но перед развёртыванием вам всё равно стоит отдать этот код на проверку людям с опытом в атаках на криптографию.
  • Написание собственной реализации стандартных криптографических протоколов? Вот в этом уже есть определённая новизна. Двигайтесь осмотрительно.
  • Проектирование собственного криптографического протокола поверх стандартных криптографических библиотек? Это намного более ново, чем вы себе представляете.
  • Разработка собственной криптографической библиотеки из стандартных конструкций криптографических алгоритмов? Если вы не являетесь опытным специалистом, то это опасная территория.
  • Новые конструкции криптографических алгоритмов (например, похожие на те, которые я неформально реализовал в своём посте)? Вы забрались уже слишком глубоко.
  • Альтернативы криптографическим алгоритмам? Здесь торопиться не стоит.
  • Идеи, представляющие конкуренцию фундаментальной математике, используемое в современной криптографии? Если вы ещё не пробили успешно все предыдущие слои и не продемонстрировали атаки на стандарты, существующие в соответствующих слоях, то вы, вероятно, не совсем здоровы.

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

Я думаю, считается, что недопустимы «новые конструкции», и если вы всего лишь «проектируете собственный криптографический протокол», то можно легко прийти к выводу, что вы не реализуете собственную криптографию, хотя на самом деле так и есть!

Никаких инструментов, одна некомпетентность

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

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

Если вы пользуетесь OpenSSL, например, для того, чтобы реализовать Messaging Layer Security (RFC 9420), то не можете заявлять, что не реализуете собственное крипто.

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

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

А именно на управление ключами.

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

Если изучить доступные разработчикам инструменты, предлагаемые языками программирования и экосистемами менеджеров управления пакетами опенсорсного ПО, то сложится ощущение, что все пытаются отдать пас кому-то ещё, надеясь, что проблему решат другие.

▍ Добро пожаловать в мой ад

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

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

Это крайне меня расстраивает.

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

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

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

Дополнение к статье

В комментариях начали задавать вопросы «Какими инструментами следует пользоваться?» и «Как всё это изучать?»

К счастью, я уже написал об этом пару постов.

  • What To Use Instead of PGP — подробное описание криптографического ПО для применения в конкретных сценариях использования.
  • How to Learn Cryptography As A Programmer — знакомство со множеством ресурсов, необходимых для совершенствования знаний в криптографии, если у вас уже есть опыт в разработке ПО.

Автор: ru_vds

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js