AEAD и режимы: сломанный GCM
Аутентифицированное шифрование (AEAD) обещает сразу две вещи: данные скрыты и данные нельзя незаметно изменить. Это не «шифрование плюс MAC по вкусу», а конструкция, где обе операции связаны и проверяются вместе. GCM — самый распространённый AEAD в мире: он в TLS 1.2 и 1.3, в IPsec, в дисковом шифровании и в библиотеках, которыми пользуются все.
Именно поэтому у GCM есть одно требование, нарушение которого обнуляет обещание: nonce обязан быть уникальным для каждого сообщения при данном ключе. Не «случайным», не «секретным» — уникальным. Если nonce повторился, повторяется ключевой поток (конфиденциальность ломается так же, как в поточном шифре), а разность тегов двух сообщений превращается в уравнение на ключ аутентификации H, после чего подделка тега становится арифметикой.
Тема показывает конструкцию изнутри: умножение в GF(2^128), GHASH, сборку тега. Затем — три атаки: восстановление второго сообщения при повторе nonce, восстановление H по двум известным открытым текстам и подделку тега для изменённого сообщения. Заканчивается разбор тем, как проектировать протокол, чтобы повтор nonce был невозможен или безвреден: SIV, детерминированные nonce, разделение ключей.
Что такое AEAD
Интерфейс и гарантии
AEAD-схема принимает ключ, nonce, открытый текст и связанные данные (AAD), а возвращает шифртекст и тег. AAD не шифруется, но аутентифицируется: заголовки, номера последовательностей, версии протокола попадают в тег и потому не могут быть изменены.
Гарантия конфиденциальности: без ключа шифртекст неотличим от случайного. Гарантия целостности: любое изменение шифртекста, тега, nonce или AAD приводит к отказу проверки с вероятностью, близкой к единице. Порядок операций при расшифровании строгий: сначала проверка тега, только потом расшифрование и разбор полей. Если сделать наоборот, получится оракул — ровно тот, что разобран в апокрифе 5.
Почему «шифрование плюс MAC» — не то же самое
Собрать AEAD из двух примитивов можно, но надо угадать порядок и охват. Encrypt-then-MAC поверх CBC работает, MAC-then-encrypt оставляет оракул дополнения. GCM решает это конструктивно: один ключ, одна операция, тег охватывает всё. Плата — жёсткие требования к nonce и цена умножения в GF(2^128) на некоторых платформах 7.
Конструкция GCM
Ключ аутентификации и GHASH
Из ключа шифрования K выводится ключ аутентификации H = E_K(0^128). GHASH — полиномиальный хеш: входные блоки складываются и умножаются на H в поле GF(2^128) по модулю x^128 + x^7 + x^2 + x + 1 1. Схема: Y_0 = 0, Y_i = (Y_{i-1} ⊕ X_i) · H.
Конструкция описана Макгрю и Виегой 2. Поле определено над GF(2), поэтому умножение — это сдвиги и XOR, без переносов; аппаратно оно ускоряется инструкцией PCLMULQDQ. Свойство, которое нас интересует: GHASH линеен по входу при фиксированном H и полиномиален по H при фиксированном входе. Обе линейности и эксплуатируются.
Шифрование и тег
Шифрование — CTR с начальным счётчиком J_0 = nonce || 0x00000001 для 96-битного nonce; в TLS 1.2 эта же конструкция описана в RFC 5288 3. Тег: T = GHASH(H, AAD, C) ⊕ E_K(J_0). Расшифрование повторяет вычисления и сравнивает тег. Структура на рисунке 1.
Важно, что E_K(J_0) одинаково для всех сообщений с одним nonce. Это и есть точка, из которой растёт атака при повторе: маска сокращается при вычитании тегов.
Повтор nonce: две атаки сразу
Конфиденциальность
Если два сообщения зашифрованы с одним nonce, их потоки совпадают: C_1 ⊕ C_2 = P_1 ⊕ P_2. Зная один открытый текст, противник получает второй. Это в точности two-time pad из апокрифа 4, только внутри AEAD — и потому особенно обидно: разработчик выбрал «стойкий режим» и всё равно получил поточный шифр с повтором.
Целостность
Теги двух сообщений с одним nonce: T_1 ⊕ T_2 = GHASH(H, AAD_1, C_1) ⊕ GHASH(H, AAD_2, C_2), потому что E_K(J_0) сокращается. Правая часть — полином по H с коэффициентами, известными из шифртекстов; его степень равна числу блоков GHASH-входа, то есть включает и блок длины. Уравнение решается не как система линейных уравнений, а как задача о корнях полинома над GF(2^128): стандартный приём атаки — построить два таких полинома по двум парам сообщений и взять их наибольший общий делитель, который с высокой вероятностью равен H − h; стоимость полиномиальна по числу блоков 4.
Получив H, противник подделывает тег для любого сообщения: T' = T ⊕ GHASH(H, AAD, C) ⊕ GHASH(H, AAD, C'). Ключ шифрования при этом не нужен — нужен только один валидный тег и H.
Наглядный расчёт в упрощённой модели
В учебной модели, где GHASH определён как Y_i = (Y_{i-1} ⊕ C_i)·H без блока длины, для сообщения из одного блока и пустого AAD получается GHASH(H, C) = C · H, и разность тегов даёт (C_1 ⊕ C_2) · H = T_1 ⊕ T_2. Если C_1 ≠ C_2, то H = (T_1 ⊕ T_2) · (C_1 ⊕ C_2)^{-1} — одно деление в поле. Эта модель удобна для первого знакомства, но лабораторная работа использует полный GHASH с блоком длины: там после деления требуется ещё извлечь квадратный корень, а для много-блочных сообщений — решать полиномиальное уравнение. Смысл атаки тот же; отличается только объём арифметики.
В стандартном GCM (NIST SP 800-38D) GHASH получает на вход ещё и блок длины L = 0^64 ‖ len(C)_64, поэтому для одного блока шифртекста GHASH(H, C) = C·H^2 ⊕ L·H: степень повышается, и «одного деления» уже нет. Атака остаётся рабочей — меняется только техника решения уравнения на H, — но формула C·H верна лишь для оговорённой учебной модели и не должна переноситься на реальный GCM.
Подделка тега
Атака без ключа шифрования
Имея H и один валидный (C, T), противник меняет шифртекст на C' и пересчитывает тег по формуле выше. Сервер принимает сообщение: тег верный, шифртекст расшифровывается в желаемый текст. Целостность исчезла полностью, хотя AES не взломан и ключ не извлечён.
Почему это не «теоретическая» атака
В 2016 году группа исследователей просканировала Интернет и нашла тысячи TLS-серверов и библиотек, которые повторяли nonce в GCM из-за ошибок в генерации или из-за отката при перезапуске 6. Атака на nonce-reuse в GCM входит в стандартный арсенал; в учебных заданиях она воспроизводится за десятки строк кода.
Как проектировать правильно
Уникальность nonce
Nonce должен быть уникален для каждой пары «ключ, сообщение». Два рабочих способа: счётчик, который никогда не повторяется (и хранится надёжно), или случайные 96 бит с вероятностью коллизии, приемлемой для объёма сообщений. Второй способ требует оценки: при 2^32 сообщениях вероятность коллизии около 2^-33, что для большинства протоколов приемлемо, но для долгоживущих ключей — нет.
Ключ обязан меняться до исчерпания счётчика или до накопления слишком большого числа сообщений. В TLS 1.3 это зашито в дизайне: ключи обновляются, номера последовательностей не повторяются, а nonce выводится из ключа и счётчика 8.
SIV и детерминированное шифрование
Если nonce негде хранить (например, шифрование файлов), используют SIV: тег вычисляется первым как синтетический IV и подаётся в режим шифрования. Повтор nonce становится безвредным, потому что IV получается из самого сообщения; цена — невозможность параллельного шифрования и необходимость двух проходов 5.
Другой вариант — детерминированный nonce из счётчика с гарантией уникальности на уровне хранилища: база данных выдаёт монотонный номер, и он же служит nonce.
Разделение ключей и домены
Один ключ — одно назначение. Если один и тот же ключ используется и для GCM, и для чего-то ещё, требования к nonce складываются, и ошибка в одном месте ломает другое. Вывод ключей по назначению (HKDF с разными метками) стоит дёшево и снимает целый класс ошибок.
Итоги темы
- AEAD связывает конфиденциальность и целостность в одной операции; порядок «сначала тег, потом текст» обязателен.
- GCM:
H = E_K(0^128), GHASH — полиномиальный хеш, тег маскируетсяE_K(J_0). - Повтор nonce ломает конфиденциальность (поток повторяется) и целостность (
Hвосстанавливается). - В упрощённой учебной модели (без блока длины) с одним блоком сообщения
Hвычисляется одним делением в GF(2^128); в стандартном GCM уравнение наHполиномиально и решается через НОД полиномов. - Защита: уникальный nonce, счётчики, ротация ключей, SIV, разделение ключей по назначению.
Литература
- NIST. SP 800-38D: Recommendation for Block Cipher Modes of Operation — Galois/Counter Mode. 2007. — спецификация GCM и требования к nonce.
- McGrew D., Viega J. The Galois/Counter Mode of Operation (GCM). 2004. — исходное описание конструкции и доказательства.
- RFC 5288: AES Galois Counter Mode for TLS. 2008. — как GCM встроен в TLS 1.2.
- Joux A. Authentication Failures in NIST Version of GCM. 2006. — разбор последствий повтора nonce и слабостей аутентификации.
- Rogaway P., Shrimpton T. A Provable-Security Treatment of the Key-Wrap Problem. 2006. — основания SIV и детерминированного шифрования.
- Böck H., Zauner A., Devlin S., Somorovsky J., Jovanovic P. Nonce-Disrespecting Adversaries: Practical Forgery Attacks on GCM in TLS. 2016. — измерение реальных повторов nonce в Интернете.
- RFC 5116: An Interface and Algorithms for Authenticated Encryption. 2008. — общий интерфейс AEAD и требования к nonce.
- RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3. 2018. — обновление ключей и построение nonce в TLS 1.3.