Фиксированный IV: ошибки и последствия

В режимах блочного шифрования, таких как AES-CBC, вектор инициализации (IV, Initialization Vector) играет критическую роль в обеспечении семантической безопасности. В библиотеке CryptoJS его неправильное использование, особенно фиксация одного и того же IV для множества операций шифрования, приводит к предсказуемым и часто катастрофическим последствиям для криптографической стойкости системы.

В режиме CBC каждый блок открытого текста перед шифрованием XOR-ится с предыдущим блоком шифротекста. Для первого блока используется IV:

C_1 = E_K(P_1 IV)

Далее:

C_i = E_K(P_i C_{i-1})

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

Что происходит при фиксированном IV в CryptoJS

В CryptoJS разработчики часто используют конструкцию:

CryptoJS.AES.encrypt(message, key, {
    iv: CryptoJS.enc.Hex.parse("00000000000000000000000000000000")
});

или любой другой статически заданный IV.

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

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

ciphertext1 = AES(key, iv_fixed, "secret message");
ciphertext2 = AES(key, iv_fixed, "secret message");

результат будет идентичен:

ciphertext1 == ciphertext2

Потеря семантической безопасности

Фиксированный IV делает шифрование детерминированным. Это означает, что атакующий может:

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

Особенно критично это в случаях, когда данные имеют структурированную природу: JSON, токены, идентификаторы, HTTP-заголовки.

Утечка структуры данных

Даже без знания ключа фиксированный IV позволяет наблюдать закономерности:

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

Пример:

AES(key, iv_fixed, "user=alex&role=admin")
AES(key, iv_fixed, "user=alex&role=user")

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

Это приводит к утечке метаданных, даже если содержимое формально зашифровано.

Уязвимость к анализу повторяемости (pattern leakage)

При фиксированном IV атакующий может:

  • выявлять повторяющиеся запросы
  • отслеживать активность пользователей
  • сопоставлять идентичные операции в разных сессиях

Это особенно опасно в системах логирования, API-запросов и токенизации данных.

Нарушение принципа IND-CPA

Криптографическая стойкость по определению IND-CPA (indistinguishability under chosen plaintext attack) требует, чтобы шифрование одного и того же сообщения давало разные результаты при каждом вызове.

Фиксированный IV полностью разрушает это свойство. Атакующий, имея возможность шифровать произвольные сообщения, может различать зашифрованные данные и строить выводы о содержимом.

Усиление атак при частичном контроле над данными

Если атакующий может влиять на часть входного сообщения (например, через форму ввода или API), фиксированный IV позволяет:

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

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

Риск повторного использования ключа и IV

Особенно опасная комбинация:

  • один ключ
  • фиксированный IV
  • множественные независимые пользователи или сессии

В этом случае разные пользователи начинают генерировать коррелированные шифротексты, что позволяет атакующему:

  • связывать действия разных пользователей
  • восстанавливать шаблоны поведения
  • проводить деанонимизацию данных

Ошибки реализации в CryptoJS-проектах

На практике фиксированный IV часто появляется из-за:

  • попытки «упростить» шифрование
  • желания получить воспроизводимые результаты для тестов
  • неправильного понимания роли IV
  • копирования небезопасных примеров кода

Типичный антипример:

const iv = CryptoJS.enc.Hex.parse("00000000000000000000000000000000");

function encrypt(data, key) {
    return CryptoJS.AES.encrypt(data, key, { iv }).toString();
}

Такой код внешне корректен, но криптографически уязвим.

Косвенные последствия в реальных системах

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

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

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

Поведение при ошибках и криптоанализе

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

Корректная модель использования IV

Правильная модель требует:

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

Типовой безопасный подход в CryptoJS:

const iv = CryptoJS.lib.WordArray.random(16);

const encrypted = CryptoJS.AES.encrypt(message, key, {
    iv: iv
});

IV затем обычно передаётся вместе с результатом:

iv + ciphertext

Системные последствия игнорирования требований IV

Игнорирование уникальности IV фактически сводит безопасность AES-CBC к уровню простого детерминированного шифра, где:

  • одинаковый вход → одинаковый выход
  • структура данных частично раскрывается
  • криптографическая защита деградирует до уровня обфускации

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