CTR (Counter) режим относится к потоковым режимам блочного шифрования, в которых AES перестаёт работать как «блочный» алгоритм в классическом смысле и превращается в генератор псевдослучайного потока байт. Этот поток затем побайтно накладывается на исходные данные при помощи операции XOR. В результате получается шифротекст, который по структуре не зависит от длины исходного сообщения и не требует дополнения (padding).
В основе CTR лежит идея использования счётчика, который шифруется с помощью блочного шифра (например, AES), а результат используется как ключевой поток.
Каждый блок данных обрабатывается следующим образом:
y = A B
где:
Главное свойство CTR заключается в том, что шифрование и расшифрование выполняются одной и той же операцией XOR, что делает режим симметричным и простым в реализации.
Счётчик в CTR состоит из двух частей:
Типичная структура блока:
[ nonce (обычно 64 бита) | counter (обычно 64 бита) ]
Или иной вариант, зависящий от реализации, но принцип остаётся одинаковым: каждый новый блок использует увеличенное значение счётчика.
Каждый блок шифрования выглядит так:
CTR_i = E_K(Nonce i)
где:
Критически важно, что nonce должен быть уникальным для каждого шифрования с одним и тем же ключом.
CTR обладает рядом характеристик, которые отличают его от CBC и других режимов:
Однако эти преимущества сопровождаются строгими требованиями к уникальности nonce.
В библиотеке Crypto-js режим CTR доступен через модуль modes.CTR и используется совместно с AES.
Пример базового шифрования:
import CryptoJS from "crypto-js";
const message = "Секретное сообщение";
const key = CryptoJS.enc.Utf8.parse("1234567890123456");
const iv = CryptoJS.enc.Utf8.parse("1234567890123456");
const encrypted = CryptoJS.AES.encrypt(message, key, {
iv: iv,
mode: CryptoJS.mode.CTR,
padding: CryptoJS.pad.NoPadding
});
console.log(encrypted.toString());
Расшифрование выполняется аналогично:
const decrypted = CryptoJS.AES.decrypt(encrypted, key, {
iv: iv,
mode: CryptoJS.mode.CTR,
padding: CryptoJS.pad.NoPadding
});
console.log(decrypted.toString(CryptoJS.enc.Utf8));
Здесь важно понимать, что iv фактически играет роль начального значения счётчика.
Crypto-js не всегда явно разделяет nonce и counter как отдельные сущности. Вместо этого:
Это означает, что безопасность полностью зависит от правильного управления iv.
CTR считается безопасным только при строгом соблюдении нескольких правил:
Если один и тот же nonce используется дважды с одинаковым ключом, происходит утечка информации:
C_1 C_2 = P_1 P_2
Это позволяет атакующему восстановить структуру исходных данных.
Если значение counter легко угадывается, криптографическая стойкость резко падает.
Так как CTR работает как потоковый режим, ошибка в одном блоке не распространяется на другие, но приводит к повреждению конкретного участка данных.
CTR принципиально отличается от CBC:
Эти свойства делают CTR предпочтительным для высокопроизводительных систем.
CTR используется в ситуациях, где важны:
Типичные области применения: