Атаки на основе повторного использования IV

Инициализационный вектор (IV, Initialization Vector) и одноразовый вектор (nonce) используются для того, чтобы одинаковые открытые сообщения при одинаковом ключе давали различный шифртекст. В современных режимах работы блочных шифров IV перестал быть просто «дополнительными данными» и превратился в критически важный элемент криптографической стойкости.

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

В библиотеке SJCL (Stanford Javascript Crypto Library) это особенно важно, поскольку типичные сценарии использования включают CTR, CBC и аутентифицированные режимы, такие как CCM и OCB2, где повтор IV приводит к детерминированным и предсказуемым последствиям.


Повторное использование IV в режиме CTR

Режим CTR (Counter Mode) превращает блочный шифр в потоковый. Генерация шифртекста происходит по схеме:

  • шифруется IV + счётчик
  • результат XOR’ится с открытым текстом

y = P E_K(IV + i)

где:

    1. — открытый текст
  • (E_K) — шифрование AES
    1. — счётчик блока

Критическая уязвимость возникает при повторном использовании IV с тем же ключом. Если два сообщения зашифрованы с одинаковым IV:

C_1 = P_1 S, C_2 = P_2 S

где поток (S) идентичен.

При XOR двух шифртекстов поток исключается:

C_1 C_2 = P_1 P_2

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

В SJCL использование CTR требует строгого контроля генерации IV. Ошибки типичны в случаях:

  • использование фиксированного IV (например, нулевого)
  • генерация IV на основе времени с малой энтропией
  • повторное использование nonce при рестарте приложения

CBC и атаки при повторении IV

CBC (Cipher Block Chaining) использует IV для первого блока:

C_1 = E_K(P_1 IV)

Если два сообщения зашифрованы с одинаковым IV, то первый блок становится уязвимым к анализу:

C_1^{(a)} C_1^{(b)} = E_K(P_1^{(a)} IV) E_K(P_1^{(b)} IV)

Хотя CBC менее подвержен прямому раскрытию XOR-структуры, повтор IV приводит к утечке:

  • одинаковых префиксов сообщений
  • повторяющихся блоков
  • возможности проведения chosen-plaintext атак

Особенно опасно это в веб-приложениях, где SJCL используется для шифрования структурированных данных (JSON, токены, cookies).


CCM и критичность nonce reuse

Режим CCM (Counter with CBC-MAC) совмещает аутентификацию и шифрование. Он использует nonce, который должен быть уникальным для каждого сообщения.

При повторе nonce происходит сразу два негативных эффекта:

  1. Повторяется поток шифрования CTR
  2. Повторяется MAC-цепочка CBC-MAC

Формально:

S = E_K(Nonce counter)

и при повторе nonce:

S_1 = S_2

Это приводит к:

  • раскрытию XOR между двумя открытыми текстами
  • возможности подмены сообщений с сохранением валидного MAC при определённых условиях
  • нарушению целостности аутентификации

В SJCL CCM считается безопасным только при строгой генерации nonce, обычно через криптографически стойкий генератор или счётчик с гарантией отсутствия повторов.


OCB2 и проблемы повторного IV

OCB2 (Offset Codebook Mode 2), реализованный в SJCL, объединяет шифрование и аутентификацию в один проход. Его безопасность критически зависит от уникальности nonce.

При повторном nonce:

  • повторяются маски блоков
  • нарушается уникальность тегов аутентификации
  • возможна частичная утечка открытого текста

OCB2 исторически имеет дополнительную сложность: при неправильной реализации повтор nonce может приводить к более сильным атакам, чем в CTR или CBC, из-за тесной связи между шифрованием и аутентификацией.


Типичные ошибки в JavaScript-реализациях SJCL

На практике проблемы возникают не в алгоритмах, а в способах их применения.

1. Фиксированный IV

var iv = [0, 0, 0, 0];

Такое использование полностью уничтожает семантическую стойкость CTR и CBC.


2. Использование Math.random()

var iv = [];
for (var i = 0; i < 4; i++) iv.push(Math.random() * 0xffffffff);

Math.random() не является криптографически стойким источником. Повторяемость последовательностей в разных окружениях приводит к предсказуемым IV.


3. Повтор nonce при сериализации состояния

В SPA-приложениях часто сохраняется состояние шифрования, включая nonce. При восстановлении состояния разработчики повторно используют старый IV.


4. Использование timestamp как IV

var iv = [Date.now()];

Временная метка обладает низкой энтропией и предсказуема. При массовых запросах приводит к коллизиям.


Последствия повторного использования IV

Повтор IV в SJCL приводит к различным уровням компрометации в зависимости от режима:

  • CTR: полное раскрытие XOR между сообщениями
  • CBC: утечка структуры и повторяющихся блоков
  • CCM: нарушение аутентификации и шифрования одновременно
  • OCB2: комбинированные атаки на целостность и конфиденциальность

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


Требования к корректной генерации IV в SJCL

Криптографически корректное использование требует:

  • уникальности IV для каждого шифрования
  • генерации через sjcl.random.randomWords
  • достаточной длины (обычно 96–128 бит)
  • исключения повторного использования при восстановлении состояния

Пример корректного подхода:

var iv = sjcl.random.randomWords(4);
var cipher = sjcl.encrypt(key, data, { iv: iv });

Ключевой принцип — отсутствие любой детерминированности в генерации IV, даже косвенной.


Влияние повторного IV на протоколы поверх SJCL

При использовании SJCL в протоколах уровня приложения (JWT-подобные токены, защищённые cookies, обмен сообщениями) повтор IV приводит к системным последствиям:

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

В потоковых режимах это превращается в устойчивую утечку информации даже при отсутствии прямого дешифрования.


Криптографическая интерпретация проблемы

Повтор IV фактически означает повтор использования одного и того же keystream’а:

S = E_K(IV)

и при повторе:

S_1 = S_2 C_1 C_2 = P_1 P_2

Это эквивалентно классической атаке на одноразовый блокнот при повторном использовании ключа.