image Привет, Хаброжители!

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

Изучите приемы, которые используют разработчики, системные администраторы и специалисты по безопасности в своей повседневной работе. Вы не встретите ни сложных математических выкладок, ни умопомрачительного жаргона: современные криптографические методы рассматриваются с помощью понятных графиков и практических примеров. Познакомьтесь с хеш-функциями и подписями, криптографическими протоколами и безопасным обменом сообщениями, а также с передовыми достижениями, такими как постквантовая криптография и криптовалюты. Читать «Реальную криптографию» одно удовольствие и, возможно, она спасет, когда в следующий раз злоумышленники покусятся на ваши данные.
Для кого эта книга
Далее я перечислю категории людей, которым, по моему мнению, будет полезна эта книга.

Студенты

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

Практикующие специалисты

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

Разработчики, прямо или косвенно использующие криптографию

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

Криптографы, интересующиеся другими областями

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

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

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

Люди, которые хотят узнать о криптографии, применяемой в реальной жизни

Чтобы прочитать эту книгу, не обязательно принадлежать к какой-то из перечисленных категорий специалистов. Если вас интересуют способы использования криптографии в реальном мире, этого будет достаточно. Однако имейте в виду, что здесь я не касаюсь истории криптографии и основ информатики, так что, прежде чем браться за чтение, не помешает получить хоть какое-то представление о криптографии.
Структура книги
Книга «Реальная криптография» состоит из двух частей. Первую следует прочитать от начала до конца, так как она охватывает криптографические ингредиенты, которые вы будете использовать в качестве строительных блоков для создания более сложных систем и протоколов.
  • Глава 1 представляет собой введение в реальную криптографию, дающее некоторое представление о том, что вы узнаете далее в книге.
  • Глава 2 посвящена хеш-функциям — фундаментальному криптографическому алгоритму, используемому для создания уникальных идентификаторов из байтовых строк.
  • В главе 3 рассказывается об использовании имитовставок, аутентификации данных и о том, как можно предотвратить изменение ваших сообщений третьими лицами.
  • В главе 4 речь пойдет о шифровании, позволяющем двум собеседникам скрыть свои коммуникации от посторонних глаз.
  • В главе 5 рассказывается об обмене ключами, который позволяет согласовывать общий секрет с другой стороной в интерактивном режиме.
  • В главе 6 описывается асимметричное шифрование, которое позволяет нескольким людям шифровать сообщения, адресованные одному человеку.
  • В главе 7 рассказывается о цифровых подписях — криптографических аналогах рукописной подписи, сделанной на бумаге.
  • В главе 8 речь пойдет о случайности и о способах управления собственными секретами.
  • Часть II книги посвящена системам, состоящим из компонентов, описанных в первой части.
  • В главе 9 вы узнаете об использовании шифрования и аутентификации для защиты каналов связи между машинами, в частности о протоколе SSL/TLS.
  • Глава 10 посвящена сквозному шифрованию, позволяющему людям вроде нас с вами доверять друг другу.
  • В главе 11 рассказывается о том, как машины аутентифицируют людей и как люди могут помочь машинам синхронизироваться друг с другом.
  • Глава 12 знакомит читателей с зарождающейся криптовалютной сферой.
  • Глава 13 посвящена аппаратной криптографии — устройствам, которые можно использовать для предотвращения извлечения ключей.
Далее следуют две бонусные главы: глава 14, посвященная постквантовой криптографии, и глава 15, посвященная криптографии следующего поколения. Эти два направления начинают проявляться в продуктах различных компаний, потому что постепенно становятся либо все более актуальными, либо все чаще применяемыми на практике и эффективными. Если вы пропустите эти две главы, я не стану вас осуждать, однако вам непременно следует прочитать заключительную главу, прежде чем поставить книгу на полку. В главе 16 кратко изложены различные проблемы и уроки, о которых необходимо помнить специалисту по криптографии, то есть вам. Как говорил дядя Человека-паука: «С большой силой приходит большая ответственность».

Имитовставки


Если смешать хеш-функцию с секретным ключом, то получится так называемый код аутентификации сообщения, или имитовставка (message authentication code, MAC) — криптографический примитив, используемый для защиты целостности данных. Добавление секретного ключа — это основа любого типа безопасности: без ключа нереально обеспечить ни конфиденциальность, ни подлинность. Хеш-функции могут обеспечить подлинность или целостность произвольных данных, но не сами по себе, а благодаря дополнительному доверенному каналу, который невозможно подделать. В этой главе мы рассмотрим, каким образом используется имитовставка для создания такого доверенного канала и что еще она может делать.

ПРИМЕЧАНИЕ

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

ФАЙЛЫ COOKIE БЕЗ СОХРАНЕНИЯ СОСТОЯНИЯ: ПОЯСНЯЮЩИЙ ПРИМЕР ИМИТОВСТАВОК


Представьте следующий сценарий: вы — веб-страница. Вы яркая, красочная и особенно гордитесь тем, что обслуживаете сообщество лояльных пользователей. Для взаимодействия с вами посетители должны войти в систему, отправив вам свои учетные данные, которые нужно проверить. Если учетные данные совпадают с теми, которые были введены при регистрации, то аутентификация пользователя проходит успешно.

Разумеется, просмотр веб-страниц состоит не из одного, а из множества запросов. Чтобы пользователям не приходилось заново проходить аутентификацию при каждом запросе, их браузер может хранить учетные данные и автоматически отправлять их серверу в нужный момент. Для этого в браузерах предусмотрена функция cookies! Файлы cookie предназначены не только для учетных данных: в них можно хранить все, что пользователь должен отправлять при каждом запросе.

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


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

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

Второй простой подход заключается в том, чтобы хранить в cookie не только имя пользователя, но и его дайджест. Для хеширования имени пользователя можно применить хеш-функцию типа SHA-3 (рис. 3.1). Как вы думаете, это сработает?


Рис. 3.1. Для аутентификации запросов веб-сервер просит браузер сохранить имя пользователя и его хеш и отправлять эту информацию с каждым последующим запросом

Здесь возникает большая проблема. Не стоит забывать, что хеш-функция является публичным алгоритмом и может быть пересчитана злоумышленником на основе новых данных. Хеш не обеспечивает целостности данных, если нет доверия к его источнику! На рис. 3.2 показано, что если злоумышленник изменит имя пользователя в cookie, то он может просто пересчитать дайджест.


Рис. 3.2. Злоумышленник может изменить информацию, содержащуюся в его файлах cookie. Если cookie содержит имя пользователя и хеш, он может изменить оба эти параметра и выдать себя за другого пользователя

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

Имитовставкой называется алгоритм с использованием секретного ключа, который принимает не только входные данные, как хеш-функция, но и (кто бы мог подумать?) секретный ключ. Выходом MAC является уникальный аутентификационный тег. Данный процесс детерминирован: при одном и том же секретном ключе и одном и том же сообщении MAC выдает один и тот же аутентификационный тег (рис. 3.3).


Рис. 3.3. Работа имитовставки. Алгоритм принимает секретный ключ и сообщение и детерминированно возвращает уникальный аутентификационный тег. Должно быть невозможно воспроизвести этот тег без ключа

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

Для подтверждения подлинности cookie вы делаете то же самое: создаете аутентификационный тег из секретного ключа и имени пользователя, находящегося в cookie, и проверяете, совпадает ли он с содержимым cookie. Если совпадает, значит, он точно ваш, так как только вы могли создать такой тег (со своим секретным ключом). На рис. 3.4 наглядно показан процесс проверки.


Рис. 3.4. Злоумышленник подделывает cookie, но не может создать актуальный аутентификационный тег для него. В результате веб-страница не может подтвердить подлинность и целостность нового cookie и, соответственно, отклоняет запрос

MAC — это как закрытая хеш-функция, которую можете вычислить только вы, поскольку знаете ключ. В некотором смысле с помощью ключа можно персонализировать хеш-функцию. Но этим связь MAC с хеш-функциями не ограничивается. Далее в этой главе мы увидим, что хеш-функции часто служат основой для построения имитовставок. Рассмотрим новый пример с использованием реального кода.

ПРИМЕР С КОДОМ


До этого момента только вы использовали MAC. Давайте в качестве стимула для написания кода увеличим число участников и посмотрим, как MAC применяются на практике. Представьте, что вы хотите общаться с человеком, при этом приватность переписки для вас неважна. Но что вас действительно волнует, так это целостность сообщений: они должны оставаться неизменными! Для этого вы и ваш собеседник должны использовать один и тот же секретный ключ вместе с имитовставкой.

В данном примере задействуем одну из наиболее популярных MAC-функций — имитовставку, использующую хеш-функции (hash-based message authentication code, HMAC), на языке программирования Rust. Другими словами, HMAC — это код аутентификации сообщений, в основе которого лежит хеш-функция. Он совместим с различными хеш-функциями, но чаще всего применяется в сочетании с SHA-2. Как показано в листинге 3.1, отправляющая сторона просто принимает ключ и сообщение и возвращает аутентификационный тег.

Листинг 3.1. Отправка аутентифицированного сообщения в Rust


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

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

Листинг 3.2. Получение аутентифицированного сообщения в Rust


СВОЙСТВА БЕЗОПАСНОСТИ ИМИТОВСТАВКИ


Имитовставки, как и все криптографические примитивы, имеют свои особенности и подводные камни. Прежде чем продолжить, я дам несколько пояснений, какие свойства безопасности обеспечивают MAC и как их правильно применять. Вы узнаете (именно в таком порядке), что:
  • имитовставки устойчивы к подделке аутентификационных тегов;
  • аутентификационный тег считается безопасным, если имеет минимальную длину;
  • примитивно аутентифицированные сообщения могут быть воспроизведены;
  • проверка аутентификационного тега склонна к ошибкам.

Подделка аутентификационного тега


Главная задача MAC, связанная с безопасностью, состоит в том, чтобы предотвратить подделку аутентификационного тега нового сообщения. Не зная секретного ключа k, нельзя вычислить аутентификационный тег t = MAC(k, m) для выбранных сообщений m. Звучит логично, не так ли? Мы не можем вычислить функцию, если нам не хватает какого-либо аргумента.

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

ПРИМЕЧАНИЕ

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

По сути, защита от таких подделок работает до тех пор, пока секретный ключ, используемый вместе с MAC, остается секретным. Из этого следует, что секретный ключ должен быть достаточно случайным (подробнее об этом — в главе 8) и достаточно большим (обычно 16 байт). Кроме того, имитовставка уязвима для уже упомянутого в главе 2 типа неоднозначной атаки. Если вам нужно аутентифицировать структуры, перед этим обязательно сериализуйте их с помощью MAC. В противном случае вполне вероятно, что подделка станет тривиальной задачей.

Длина аутентификационного тега


Другой возможной атакой на MAC являются коллизии. Напомню, что найти коллизию для хеш-функции означает найти два различных входных блока А и Б, таких, что хеш(А) = хеш(Б). Это определение верно и для имитовставок: коллизия считается найденной при MAC(k, А) = MAC(k, Б) для входных блоков А и Б.

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

[Запрос аутентификационных тегов] займет 250 000 лет в непрерывном канале связи со скоростью 1 Гбит/с, и только если в течение всего этого времени секретный ключ K останется прежним.

RFC 2104 («HMAC: Имитовставка, использующая хеш-функции с ключом», 1997)


Применение 128-битного аутентификационного тега может показаться нелогичным, поскольку выход хеш-функции должен быть длиной 256 бит. Однако хеш-функции являются публичными алгоритмами, которые можно вычислить в автономном режиме, что позволяет злоумышленнику оптимизировать и распараллелить атаку. Такая функция с ключом, как MAC, вынуждает его напрямую запрашивать аутентификационные теги, что обычно существенно замедляет атаку. Таким образом, если длина аутентификационного тега 128 бит, то для того, чтобы найти коллизию с вероятностью 50 %, злоумышленник должен сделать онлайн-запроса. Это уже достаточно большой показатель. Тем не менее при желании можно увеличить аутентификационный тег до 256 бит.

Атаки повторного воспроизведения


Я еще не упомянул об атаках повторного воспроизведения. Представьте, что Алиса и Боб открыто общаются, используя незащищенное соединение. Они защищают свои сообщения от подделки, добавляя аутентификационный тег к каждому из них. Более того, в соответствии с передовой практикой оба они имеют собственный секретный ключ для защиты своей стороны соединения. Процесс их общения изображен на рис. 3.5.


Рис. 3.5. Два пользователя, имеющие два ключа, k1 и k2, обмениваются сообщениями, содержащими аутентификационные теги. Эти теги вычисляются из k1 или k2 в зависимости от направления сообщения. Злоумышленник пересылает одно из сообщений пользователю

В этом случае ничто не мешает злоумышленнику воспроизвести одно из сообщений для его получателя. Протокол, в основе которого лежит имитовставка, должен знать об этом и иметь средства защиты от такого вмешательства. Один из способов — добавление счетчика прямого отсчета на вход MAC (рис. 3.6).

Как правило, счетчики имеют фиксированную длину 64 бита. Такой размер позволяет отправить 264 сообщения до достижения лимита счетчика (с риском его обхода и повторения).


Рис. 3.6. Два пользователя, имеющие два ключа, k1 и k2, обмениваются сообщениями, содержащими аутентификационные теги. Эти теги вычисляются из k1 или k2 в зависимости от направления сообщений. Злоумышленник пересылает одно из сообщений пользователю. Поскольку жертва увеличила свой счетчик, тег, вычисленный на основании «2, хорошо, а у тебя?», не совпадет с тегом злоумышленника, что позволяет жертве успешно заблокировать воспроизведенное сообщение

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

УПРАЖНЕНИЕ

Как вы думаете, каким образом счетчик переменной длины мог бы позволить злоумышленнику подделать аутентификационный тег?

Проверка аутентификационных тегов за постоянное время


Последняя проблема очень важна для меня, так как во время аудита я неоднократно находил эту уязвимость в приложениях. При проверке аутентификационного тега сравнение полученного тега с вычисленным должно занимать постоянное время. Это означает, что сравнение всегда должно занимать одно и то же время при условии, что полученный тег имеет правильный размер. Если время сравнения двух аутентификационных тегов варьируется, значит, скорее всего, алгоритм возвращается в момент, когда сравниваемые теги различаются. Обычно это дает злоумышленнику достаточно информации для проведения атак, которые позволяют воссоздать актуальный аутентификационный тег байт за байтом, измеряя время, необходимое для завершения проверки. В следующем комиксе объяснена эта проблема. Мы называем такие атаки атаками по времени.


К счастью, криптографические библиотеки, реализующие MAC, также предоставляют удобные функции для проверки аутентификационного тега за постоянное время. Если вам интересно, что они собой представляют, то в листинге 3.3 показано, как Golang реализует сравнение аутентификационных тегов в коде постоянного времени.

Листинг 3.3. Выполнение сравнения за постоянное время в Golang

for i := 0; i < len(x); i++ {
    v |= x[i] ^ y[i]
}

Фокус заключается в том, что здесь пропускается любое ветвление. Ответ на вопрос, как именно это работает, мы оставляем читателю в качестве задания.

ИМИТОВСТАВКА В РЕАЛЬНОМ МИРЕ


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

Аутентификация сообщения


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

Получение ключей


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

ПСЕВДОСЛУЧАЙНАЯ ФУНКЦИЯ

Представьте себе набор из всех функций, которые принимают входные данные переменной длины и возвращают случайный результат фиксированного размера. Было бы замечательно, если бы мы могли выбрать из него произвольную функцию и использовать ее в качестве имитовставки (без ключа). Оставалось бы договориться о конкретной функции, как при согласовании ключа. К сожалению, у нас нет такой возможности, поскольку набор слишком велик. Тем не менее мы можем эмулировать выбор случайной функции, разработав нечто довольно близкое к ней — псевдослучайную функцию (pseudorandom function, PRF). HMAC и большинство практических MAC — именно такие конструкции. Они рандомизируются по аргументу ключа. Выбор другого ключа аналогичен выбору случайной функции.

УПРАЖНЕНИЕ

Внимание: не все MAC являются PRF. Как вы думаете — почему?

Целостность файлов cookie


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

Хеш-таблицы


Языки программирования обычно предоставляют такие структуры данных, как хеш-таблицы (также называемые хеш-картами, словарями, ассоциированными массивами и т. д.), которые используют некриптографические хеш-функции. Если сервис предоставляет хеш-таблицы таким образом, что входные данные некриптографической хеш-функции могут контролироваться злоумышленниками, против него может быть произведена атака «отказ в обслуживании» (denial of service attacks, DoS), которая подразумевает выведение сервиса из строя. Для предотвращения такой атаки некриптографическая хеш-функция обычно рандомизируется в начале работы программы.

Во многих крупных приложениях вместо некриптографической хеш-функции используется имитовставка со случайным ключом. Так обстоит дело во многих языках программирования, например Rust, Python, Ruby, или в крупных приложениях, например в ядре Linux. Все они применяют так называемый SipHash, то есть MAC, оптимизированный для получения коротких аутентификационных тегов со случайным ключом, который генерируется в начале работы программы.

ПРАКТИЧЕСКОЕ ИСПОЛЬЗОВАНИЕ ИМИТОВСТАВОК


Итак, имитовставки представляют собой криптографические алгоритмы, которые могут применяться между одной или несколькими сторонами для сохранения целостности и подлинности информации. Поскольку широко распространенные имитовставки являются также хорошими источниками случайности, их часто задействуют для детерминированной генерации случайных чисел в различных типах алгоритмов, например в алгоритме одноразовых паролей с временным параметром (time-based one-time password, TOTP), с которым вы познакомитесь в главе 11. В этом разделе рассмотрим два стандартных алгоритма имитозащиты, которые можно задействовать в настоящее время, — HMAC и KMAC.

HMAC — имитовставка с использованием хеш-функции


Наиболее распространенным MAC является HMAC (hash-based MAC), изобретенный в 1996 году М. Беллар, Р. Канетти и Х. Кравчиком и описанный в RFC 2104, FIPS Publication 198 и ANSI X9.71. Как следует из названия, HMAC представляет собой способ применения хеш-функций с ключом. Использование хеш-функции для построения MAC — популярная концепция, поскольку хеш-функции широко распространены, быстро реализуются с помощью ПО и имеют аппаратную поддержку в большинстве систем. Вспомните, в главе 2 я говорил о том, что SHA-2 не следует использовать непосредственно для хеширования секретов из-за ее уязвимости к атакам удлинением сообщения (подробнее об этом — в конце главы). Как же определить, каким образом преобразовать хеш-функцию в функцию с ключом? Эту задачу решает HMAC. С точки зрения внутреннего устройства HMAC выполняет следующие шаги, наглядно продемонстрированные на рис. 3.7.
  1. Сначала из основного ключа получают два ключа, k1 = kipad и k2 = kopad, где ipad (внутреннее дополнение, от inner padding) и opad (внешнее дополнение, от outer padding) — константы, ⊕ — символ операции XOR.
  2. Затем HMAC объединяет ключ k1 с сообщением и хеширует его.
  3. Полученный результат объединяется с ключом k2 и хешируется еще раз.
  4. Таким образом получается конечный аутентификационный тег.


Рис. 3.7. HMAC работает путем хеширования конкатенации (||) ключа k1 и входного сообщения с последующим хешированием конкатенации ключа k2 с результатом предыдущей операции; k1 и k2 детерминированно выводятся из секретного ключа k

Поскольку HMAC — это настраиваемый алгоритм, размер его аутентификационного тега определяется применяемой хеш-функцией. Например, HMAC-SHA-256 использует SHA-256 и выдает аутентификационный тег размером 256 бит, HMAC-SHA-512 выдает аутентификационный тег размером 512 бит и т. д.

ВНИМАНИЕ
Как мы говорили ранее, несмотря на то что размер выхода HMAC можно усечь, аутентификационный тег должен быть не менее 128 бит. Тем не менее это правило соблюдается не всегда, так как некоторые приложения обходятся 64 битами из-за явной необходимости обработки ограниченного количества запросов. Такой подход предусматривает некоторые компромиссы, и опять же, прежде чем делать что-то нестандартное, важно изучить все мелочи.

Конструкция HMAC обусловлена необходимостью упрощения доказывания. В ряде работ подтверждена надежность защиты HMAC от подделок при условии, что хеш-функция в его основе обладает свойствами, которыми должны обладать все безопасные хеш-функции с криптографической точки зрения. Благодаря этому мы можем использовать HMAC в сочетании с большим количеством хеш-функций. Сегодня HMAC в основном применяется с SHA-2.

KMAC — имитовставка с использованием cSHAKE


Поскольку SHA-3 неуязвима для атак удлинением сообщения (что было одним из условий конкурса по разработке SHA-3), не имеет смысла задействовать этот алгоритм с HMAC вместо, например, эффективного SHA-3-256(ключ || сообщение), чем по сути и является KMAC.

KMAC использует cSHAKE — настраиваемую версию функции расширенного выхода SHAKE (XOF), рассмотренную в главе 2. Он однозначно шифрует MAC-ключ, входное сообщение и требуемую длину выхода (KMAC является своего рода расширенным выходом MAC) и отдает это все cSHAKE в качестве входных данных для впитывания (рис. 3.8). KMAC также использует «KMAC» в качестве имени функции (для настройки cSHAKE) и, ко всему прочему, может принимать заданную пользователем строку настройки.


Рис. 3.8. KMAC — это просто обертка вокруг cSHAKE. Чтобы применять ключ, он шифрует (однозначным образом) ключ, входное сообщение и длину выхода и передает результат на вход cSHAKE

Интересно отметить: поскольку KMAC впитывает требуемую длину выхода, то несколько запросов с разной длиной выхода будут иметь совершенно разные результаты, что, как правило, нетипично для XOF. Эта особенность делает KMAC довольно универсальной функцией.

SHA-2 И АТАКИ УДЛИНЕНИЕМ СООБЩЕНИЯ


Мы уже неоднократно говорили о том, что не следует хешировать секреты с помощью SHA-2, поскольку она неустойчива к атакам удлинением сообщения. В этом разделе попытаемся дать простое объяснение этой атаки.

Вернемся к примеру из вводной части главы — к тому шагу, когда мы попытались применить SHA-2 для защиты целостности файла cookie. Если вы помните, этот вариант оказался неприемлемым, так как пользователь может подделать cookie (например, добавив поле admin=true) и пересчитать его хеш. Поскольку SHA-2 — публичная функция, ничто не помешает ему сделать это. На рис. 3.9 изображено такое вмешательство.


Рис. 3.9. Веб-страница посылает файл cookie и его хеш пользователю. Для аутентификации последний должен отправлять этот cookie при каждом новом запросе. К сожалению, злоумышленник может подделать cookie и пересчитать его хеш, нарушив тем самым проверку целостности. В результате веб-страница принимает новый файл cookie, как будто он верный

Если добавить секретный ключ к хешируемому элементу, пользователь не сможет пересчитать дайджест, поскольку для этого ему потребуется секретный ключ, как в случае с MAC. Таким образом, при получении поддельного файла cookie страница вычисляет алгоритм SHA-256(ключ || поддельный_cookie), где || представляет собой конкатенацию двух значений, и получает результат, не совпадающий с тем, что, вероятно, прислал злоумышленник. Этот подход иллюстрирует рис. 3.10.


Рис. 3.10. Использование ключа при вычислении хеша cookie позволяет предположить, что злоумышленник, желающий подделать собственный cookie, не сможет вычислить правильный дайджест по новому cookie. Однако, как мы увидим далее, для SHA-256 этот вариант не работает

К сожалению, SHA-2 имеет досадную особенность: из дайджеста по входным данным можно вычислить дайджест входного сообщения и даже больше. Что это означает? Давайте посмотрим на рис. 3.11, где показано использование SHA-256 в виде SHA-256(секрет || входные_данные1).


Рис. 3.11. SHA-256 хеширует секрет, конкатенированный с файлом cookie (входные_данные1). Напомню, что SHA-256 использует структуру Меркла — Дамгарда для итеративного вызова функции сжатия над блоками входных данных, начиная с вектора инициализации (initialization vector, IV)

Этот рисунок сильно упрощен, но представьте, что входными_данными1 является строка user=боб. Обратите внимание: полученный дайджест — это фактически полное промежуточное состояние хеш-функции на данном этапе. Ничто не мешает сделать вид, что дополнение является частью входного блока, и продолжить круговорот Меркла — Дамгарда. Эта атака проиллюстрирована на рис. 3.12: с помощью дайджеста вычисляется хеш входных_данных1 || дополнения || входных_данных2. В нашем примере входные_данные2 — это &admin=true.


Рис. 3.12. Выход, который представляет собой хеш SHA-256 cookie (средний дайджест), используется для расширения хеша на большее количество данных. В результате создается хеш (правый дайджест) секрета, конкатенированного с входными_данными1, первыми байтами дополнения и входными_данными2

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


Рис. 3.13. Злоумышленник успешно использует атаку удлинением сообщения для подделки cookie и вычисляет правильный хеш с помощью предыдущего хеша

Тот факт, что первое дополнение теперь должно быть частью входных данных, может предотвратить использование некоторых протоколов. Тем не менее самое незначительное изменение может вновь привести к появлению уязвимости. По этой причине никогда не следует хешировать секреты с помощью SHA-2. Безусловно, существует несколько способов корректного хеширования секретов с поддержкой HMAC (например, рабочим вариантом является SHA-256(k || сообщение || k)). Таким образом, если вы хотите использовать SHA-2, возьмите HMAC, а если SHA-3 — KMAC.

РЕЗЮМЕ

  • Имитовставки — это симметричные криптографические алгоритмы, позволяющие одной или нескольким сторонам, имеющим один и тот же ключ, подтвердить целостность и подлинность сообщений.
    • Для проверки подлинности сообщения и связанного с ним аутентификационного тега можно пересчитать аутентификационный тег сообщения и секретный ключ, а затем сверить полученный результат и исходный тег. Если они различаются, значит, сообщение было подделано.
    • Сравнение полученного аутентификационного тега с вычисленным должно проходить за постоянное время.
  • Хотя имитовставки по умолчанию защищают целостность сообщений, они не распознают воспроизведенные сообщения.
  • Стандартизированными и хорошо зарекомендовавшими себя MAC являются HMAC и KMAC.
  • HMAC можно задействовать вместе с различными хеш-функциями. На практике он часто используется с SHA-2.
  • Для предотвращения коллизий и подделок аутентификационные теги должны иметь минимальную длину 128 бит.
  • Никогда не применяйте SHA-256 непосредственно для построения MAC, так как существует риск неправильной реализации. Всегда берите для этой цели функцию типа HMAC.
Об авторе
Дэвид Вонг является старшим инженером по криптозащите в компании O(1) Labs, где работает над криптовалютой Mina. Ранее он возглавлял работу по обеспечению безопасности криптовалюты Diem (официально известной как Libra) в рамках проекта Novi компании Facebook, а до этого был консультантом по информационной безопасности в команде Cryptography Services компании NCC Group.

В рамках карьеры Вонг принял участие в нескольких финансируемых государством аудитах проектов с открытым исходным кодом, таких как OpenSSL и Let’s Encrypt. Он выступал на различных конференциях, в том числе DEF CON и Black Hat, в рамках которой неоднократно преподавал курс по криптографии. Внес вклад в разработку стандарта TLS 1.3 и протокольного фреймворка Noise. Обнаружил уязвимости во множестве систем, включая CVE-2016-3959 в стандартной библиотеке Golang, а также CVE-2018-12404, CVE-2018-19608, CVE-2018-16868, CVE-2018-16869 и CVE-2018-16870 в различных библиотеках TLS.

Помимо прочего, Дэвид — автор протокола Disco (www.discocrypto.com и www.embeddeddisco.com) и проекта по обеспечению безопасности децентрализованных приложений для смарт-контрактов (www.dasp.co). Его исследования посвящены атакам на кэш, направленным против алгоритма RSA (http://cat.eyalro.net/), протоколу на основе QUIC (https://eprint.iacr.org/2019/028), атакам по времени, направленным против алгоритма ECDSA (https://eprint.iacr.org/2015/839), и бэкдорам в алгоритме Диффи — Хеллмана (https://eprint.iacr.org/2016/644). Более подробную информацию можно найти в его блоге по адресу www.cryptologie.net.

Более подробно с книгой можно ознакомиться на сайте издательства:

» Оглавление
» Отрывок

По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Для Хаброжителей скидка 25% по купону — Криптография

Комментарии (0)