Режим CFB: обратная связь по шифротексту

CFB (Cipher Feedback) относится к потокоподобным режимам блочного шифрования, в которых зашифрованные данные формируются не путём независимого шифрования блоков, а через обратную связь от предыдущего шифротекста. В контексте CryptoJS этот режим используется для превращения блочного шифра AES в механизм, способный обрабатывать данные произвольной длины без необходимости дополнения (padding).

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

Пусть:

  • E_k — функция блочного шифра (например, AES)
  • IV — вектор инициализации
  • P_i — очередной блок открытого текста
  • C_i — соответствующий блок шифротекста

Процесс начинается с IV:

  1. Шифруется текущее состояние:

    S_0 = E_k(IV)
  2. Формируется первый блок шифротекста:

    C_1 = P_1 ⊕ S_0
  3. Далее состояние обновляется:

    S_1 = E_k(C_1)
  4. Для следующего блока:

    C_2 = P_2 ⊕ S_1

Таким образом, каждый новый блок зависит от предыдущего шифротекста, что создаёт цепочку обратной связи.

Особенности обратной связи

Ключевым свойством CFB является то, что шифротекст участвует в формировании следующего шага шифрования. Это приводит к следующим характеристикам:

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

Потоковый характер и сегментация

В CryptoJS режим CFB поддерживает параметр segmentSize, определяющий размер обрабатываемого сегмента в битах. Это позволяет варьировать поведение режима от блочного (128 бит) до более мелких потоковых сегментов.

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

При стандартной конфигурации AES используется блок 128 бит, однако CFB позволяет работать с меньшими сегментами, например 8 бит, что приближает поведение к побитовому потоку.

Реализация CFB в CryptoJS

В библиотеке CryptoJS режим CFB включается через объект CryptoJS.mode.CFB.

Базовый пример шифрования

const CryptoJS = require("crypto-js");

const key = CryptoJS.enc.Utf8.parse("1234567890123456");
const iv = CryptoJS.enc.Utf8.parse("abcdef9876543210");

const plaintext = "Пример данных для шифрования";

const encrypted = CryptoJS.AES.encrypt(plaintext, key, {
    iv: iv,
    mode: CryptoJS.mode.CFB,
    padding: CryptoJS.pad.NoPadding
});

console.log(encrypted.toString());

Важный момент — в CFB обычно используется отсутствие padding, поскольку режим не требует выравнивания данных по размеру блока.

Расшифрование в CFB

Особенность CFB заключается в симметричности операций: процесс шифрования и расшифрования использует одну и ту же функцию AES.

При расшифровании используется тот же механизм обратной связи:

const decrypted = CryptoJS.AES.decrypt(encrypted, key, {
    iv: iv,
    mode: CryptoJS.mode.CFB,
    padding: CryptoJS.pad.NoPadding
});

console.log(decrypted.toString(CryptoJS.enc.Utf8));

Здесь важно, что отличие между encrypt и decrypt заключается не в алгоритме AES, а в том, как интерпретируется поток XOR-операций.

Вектор инициализации (IV)

IV в CFB играет критическую роль, поскольку он определяет начальное состояние цепочки. При одинаковом ключе разные IV приводят к полностью различным шифротекстам.

Основные требования к IV:

  • уникальность для каждого шифрования;
  • достаточная длина (для AES — 128 бит);
  • отсутствие предсказуемости.

Повторное использование IV с одним и тем же ключом приводит к утечке информации о структуре данных.

Отсутствие необходимости в padding

В отличие от ECB и CBC режимов, CFB не требует дополнения данных до размера блока. Это связано с тем, что шифрование выполняется через XOR с потоком, а не через прямую обработку блоков.

Это делает режим удобным для:

  • потоковой передачи данных;
  • шифрования сетевых сообщений;
  • обработки данных неизвестной длины.

Ошибкоустойчивость и распространение искажений

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

  • ошибка в одном блоке шифротекста влияет на расшифрование текущего и следующего блока;
  • последующие блоки восстанавливаются корректно.

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

Искажение одного C_i приводит к повреждению соответствующего P_i и частично P_{i+1}, после чего поток восстанавливается.

Разновидности CFB

В зависимости от размера сегмента различают:

  • CFB-128 — классический вариант для AES, сегмент равен размеру блока;
  • CFB-8 — побайтная обработка, используется в потоковых сценариях;
  • промежуточные варианты (CFB-1, CFB-32), применяемые реже.

В CryptoJS параметр segmentSize управляет этим поведением:

CryptoJS.AES.encrypt(data, key, {
    iv: iv,
    mode: CryptoJS.mode.CFB,
    segmentSize: 8
});

Сравнение с другими режимами

CFB занимает промежуточное положение между блочными и потоковыми режимами:

  • ECB — независимые блоки, высокая уязвимость к анализу структуры;
  • CBC — требует padding, менее потоковый;
  • CTR — полноценный потоковый режим;
  • CFB — потоковый с обратной связью через шифротекст.

Ключевое отличие CFB — использование зашифрованного предыдущего состояния, а не счётчика, как в CTR.

Применение в реальных системах

CFB используется в сценариях, где требуется:

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

Типичные области:

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

Ограничения режима

Несмотря на гибкость, CFB имеет ряд ограничений:

  • зависимость от IV при каждом запуске;
  • невозможность параллельного шифрования блоков;
  • чувствительность к ошибкам передачи;
  • меньшая производительность по сравнению с CTR.

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