Атаки по времени в коде на уровне приложения
Узнайте, как время сравнения строк раскрывает секреты и как сравнение за постоянное время предотвращает такие утечки.
«Атаки по времени в коде на уровне приложения» — бесплатный урок Cryptology Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Cryptology Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Cryptology Academy содержит 4 уроков всего.
Сравнение строк не за постоянное время
Стандартный оператор сравнения строк на равенство в большинстве языков программирования завершает работу сразу после обнаружения несовпадения. Оператор == в Python для объектов bytes, strcmp в C и String.equals в Java немедленно возвращают результат при обнаружении первого различающегося байта. Для обычного сравнения строк это оптимизация, но при сравнении секретных значений, таких как теги MAC или пароли, она создаёт измеримый побочный канал по времени, который раскрывает сведения.
Измерение времени сравнения HMAC
Злоумышленник измеряет время, необходимое для сравнения представленного тега HMAC с правильным значением. Представление HMAC, у которого первый байт совпадает, занимает немного больше времени, чем представление с неверным первым байтом (выполняется одно дополнительное сравнение байтов). Отправляя множество значений с каждым возможным первым байтом и измеряя время отклика, злоумышленник определяет правильный первый байт. Затем этот процесс повторяется побайтно, пока не будет восстановлен тег целиком.
Практическая точность измерения времени при атаке
Современные сетевые атаки по времени позволяют выявлять различия во времени длительностью от десятков до сотен наносекунд через интернет. При сравнении 32-байтного тега HMAC, когда каждый правильно совпавший байт добавляет примерно 10–100 нс ко времени обработки, после достаточного количества повторных измерений возникает измеримый сигнал, позволяющий усреднить сетевой джиттер. В локальной сети при достаточном статистическом количестве измерений можно использовать даже различия длительностью в одну наносекунду.
Уязвимость оператора == в Python
В Python сравнивать теги MAC с помощью == небезопасно: выражение if mac == submitted_mac возвращает True или False в зависимости от позиции первого несовпадения. Отправляя тысячи специально сформированных тегов и измеряя время отклика, злоумышленник может побайтно восстановить ожидаемый тег. Эта уязвимость встречалась в рабочих веб-приложениях, где сравнение маркеров сеанса или ключей API было неправильно реализовано без функций, выполняющих сравнение за постоянное время.
hmac.compare_digest в Python
Функция hmac.compare_digest(a, b) в Python сравнивает два значения — байтовых или строковых — за постоянное время, занимая одинаковое время независимо от положения первого несовпадения. Она реализована на C, чтобы обеспечить постоянное время выполнения даже с учетом накладных расходов интерпретации байткода Python. Всегда используйте hmac.compare_digest для сравнения тегов MAC, маркеров сеанса, ключей API или любых значений, утечка информации о времени обработки которых может быть опасной.
CRYPTO_memcmp в OpenSSL
OpenSSL предоставляет функцию CRYPTO_memcmp(a, b, length) для сравнения областей памяти за постоянное время. В отличие от memcmp, она всегда обрабатывает все байты, заданные параметром length, независимо от ранних несовпадений. Возвращаемое значение равно нулю, если значения равны, и ненулю, если они различаются. Важно всегда сравнивать значения полностью ожидаемой длины: сравнение значений разной длины только по меньшей длине все равно может раскрыть информацию об их длине. Используйте CRYPTO_memcmp при любом критически важном для безопасности сравнении в коде на C/C++ с применением OpenSSL.
Атаки по времени на RSA: Блейхенбахер
Атаки по времени не ограничиваются сравнением строк. Атака Блейхенбахера 2006 года на расшифрование RSA PKCS#1 v1.5 продемонстрировала практический оракул по времени против реализаций SSL/TLS. Время выполнения операции с закрытым ключом RSA менялось в зависимости от того, имело ли расшифрованное значение корректное дополнение PKCS#1. Отправляя тысячи специально сформированных шифротекстов, злоумышленники могли восстановить закрытые ключи RSA. Это послужило стимулом для создания RSA-OAEP и реализаций RSA с постоянным временем выполнения.
Атаки по времени через кэш на AES
Реализации AES, использующие таблицы поиска (что распространено для повышения производительности), обращаются к разным элементам таблицы в зависимости от ключа и открытого текста. Попадания в кэш и промахи кэша создают измеримые различия во времени, раскрывающие информацию о том, к каким элементам таблицы обращались. Этот побочный канал может раскрыть ключи AES. Защита заключается в использовании реализаций AES, не зависящих от поиска по таблицам, например аппаратных инструкций AES-NI или программных реализаций с разбиением на биты.
Принципы реализации за постоянное время
Для написания кода с постоянным временем выполнения необходимо избегать условных переходов, зависящих от секретных данных (используйте выбор без ветвлений с применением масок), шаблонов доступа к памяти, зависящих от секретных данных (избегайте таблиц поиска с индексами, содержащими секреты), а также любых операций, задержка которых зависит от секретных значений (например, деления на некоторых процессорах). Компиляторы могут удалить конструкции с постоянным временем выполнения в ходе оптимизации, поэтому в критических участках могут потребоваться ассемблерный код или обращения к volatile-памяти.
AEAD устраняет сравнение MAC на уровне приложения
Лучшая защита от атак по времени при сравнении MAC — использовать режимы AEAD (GCM, ChaCha20-Poly1305) и поручать проверку MAC криптографической библиотеке. Реализации библиотек внутренне выполняют проверку за постоянное время. Если вы правильно используете AEAD (расшифрование завершается ошибкой при любом изменении данных, а расшифрование никогда не выполняется до проверки тега), вам вообще не придется сравнивать теги MAC в коде приложения, что полностью устраняет уязвимость, связанную со временем выполнения.
Проверка уязвимостей к атакам по времени
Проверка уязвимостей к атакам по времени требует статистического анализа распределений времени отклика. Такие инструменты, как tlsfuzzer, скрипты для проверки атак по времени и платформа dudect, помогают обнаруживать различия во времени выполнения криптографических реализаций. t-критерий для выборок времени отклика на входных данных, для которых время выполнения должно быть одинаковым, может выявить статистически значимые различия. Возможны ложноотрицательные результаты, поэтому наряду с проверкой необходимо проводить анализ кода на постоянное время выполнения.
Сравнение за постоянное время
Какую функцию Python следует использовать для безопасного сравнения тега HMAC, чтобы предотвратить атаки по времени?
Итоги атак по времени
Итоги атак по времени: сравнение строк с досрочным завершением раскрывает секретные значения побайтно через различия во времени отклика; при достаточном количестве измерений это можно обнаружить по сети; в Python для сравнения за постоянное время используйте hmac.compare_digest, а в OpenSSL — CRYPTO_memcmp; атаки по времени на дополнение RSA компрометируют закрытые ключи (используйте RSA с постоянным временем выполнения и OAEP); атаки по времени через поиск по таблицам AES раскрывают биты ключа (используйте AES-NI или реализации с разбиением на биты); проверка библиотекой AEAD устраняет необходимость сравнивать MAC на уровне приложения.
Часто задаваемые вопросы
Урок «Атаки по времени в коде на уровне приложения» бесплатный?
Да — полный текст урока «Атаки по времени в коде на уровне приложения» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Cryptology Academy, подпишись на CoddyKit PRO. Курс Cryptology Academy содержит 4 уроков всего.
Чему я научусь в уроке «Атаки по времени в коде на уровне приложения»?
Узнайте, как время сравнения строк раскрывает секреты и как сравнение за постоянное время предотвращает такие утечки. Ты практикуешь Cryptology Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Cryptology Academy?
Предыдущий опыт не требуется. Cryptology Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Атаки по времени в коде на уровне приложения»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Cryptology Academy?
Да. Каждый урок Cryptology Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Атаки Padding Oracle подробно
- Атаки повторной передачи и уязвимости повторного использования nonce
- Атаки по времени в коде на уровне приложения
- Основные схемы неправильного использования криптографии