AES: режимы работы CBC, CTR, GCM

В библиотеке jsrsasign AES реализуется через модуль KJUR.crypto.Cipher, который предоставляет унифицированный интерфейс для симметричного шифрования. AES (Advanced Encryption Standard) используется в различных режимах работы, которые определяют способ обработки блоков данных.

Ключевые особенности AES в контексте jsrsasign:

  • поддержка ключей 128/192/256 бит
  • работа с различными режимами (CBC, CTR, GCM)
  • встроенная обработка padding (в зависимости от режима)
  • совместимость с бинарными и строковыми данными

Основная точка входа:

var cipher = new KJUR.crypto.Cipher({
  alg: "AES",
  mode: "CBC", // может быть CBC, CTR, GCM
  key: keyHex,
  iv: ivHex
});

Формирование ключей и IV

AES требует корректного размера ключа и инициализирующего вектора (IV).

Генерация ключа

var keyHex = KJUR.crypto.Util.getRandomHexOfNbytes(32); // AES-256

Генерация IV

var ivHex = KJUR.crypto.Util.getRandomHexOfNbytes(16); // всегда 16 байт для AES

IV не является секретом, но должен быть уникальным для каждого шифрования в режимах CBC и GCM.


Режим CBC (Cipher Block Chaining)

CBC является классическим режимом блочного шифрования. Каждый блок входных данных XOR-ится с предыдущим зашифрованным блоком.

Особенности CBC:

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

Шифрование в CBC

var cipher = new KJUR.crypto.Cipher({
  alg: "AES",
  mode: "CBC",
  key: keyHex,
  iv: ivHex
});

var encryptedHex = cipher.encrypt("Hello world");

Дешифрование CBC

var decipher = new KJUR.crypto.Cipher({
  alg: "AES",
  mode: "CBC",
  key: keyHex,
  iv: ivHex
});

var decryptedText = decipher.decrypt(encryptedHex);

Padding в CBC

CBC требует выравнивания блока (16 байт). В jsrsasign обычно применяется PKCS#5/PKCS#7 padding автоматически. Это важно учитывать при совместимости с другими библиотеками.


Режим CTR (Counter Mode)

CTR превращает блочный шифр в потоковый. Вместо цепочки блоков используется счётчик, который шифруется и XOR-ится с данными.

Особенности CTR:

  • не требует padding
  • параллелизуемый
  • одинаковые блоки не дают одинакового шифротекста
  • IV используется как nonce + counter

Шифрование CTR

var cipher = new KJUR.crypto.Cipher({
  alg: "AES",
  mode: "CTR",
  key: keyHex,
  iv: ivHex
});

var encryptedHex = cipher.encrypt("Hello world");

Дешифрование CTR

var decipher = new KJUR.crypto.Cipher({
  alg: "AES",
  mode: "CTR",
  key: keyHex,
  iv: ivHex
});

var decryptedText = decipher.decrypt(encryptedHex);

Особенности безопасности CTR

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


Режим GCM (Galois/Counter Mode)

GCM объединяет CTR-шифрование и механизм аутентификации данных (AEAD — Authenticated Encryption with Associated Data).

Основные свойства GCM:

  • конфиденциальность + целостность
  • встроенный MAC (authentication tag)
  • устойчивость к подмене данных
  • высокая производительность

Шифрование GCM

var cipher = new KJUR.crypto.Cipher({
  alg: "AES",
  mode: "GCM",
  key: keyHex,
  iv: ivHex,
  aad: "header-data"
});

var encryptedHex = cipher.encrypt("Hello world");
var tag = cipher.getAuthTag();

Дешифрование GCM

var decipher = new KJUR.crypto.Cipher({
  alg: "AES",
  mode: "GCM",
  key: keyHex,
  iv: ivHex,
  aad: "header-data",
  authTag: tag
});

var decryptedText = decipher.decrypt(encryptedHex);

AAD (Additional Authenticated Data)

AAD позволяет защищать метаданные без их шифрования. Например:

  • заголовки протоколов
  • идентификаторы сообщений
  • версии формата

Изменение AAD делает расшифровку невозможной, даже если ciphertext не изменён.


Сравнение CBC, CTR и GCM

CBC

  • требует padding
  • последовательно обрабатывает блоки
  • не защищает от подмены данных
  • распространён в устаревших протоколах

CTR

  • потоковый режим
  • отсутствие padding
  • высокая скорость
  • нет встроенной аутентификации

GCM

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

Типовые ошибки при работе с AES в jsrsasign

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

Одна из критических ошибок:

// опасная практика
var ivHex = "0000000000000000";

IV должен быть уникальным для каждого сообщения.


Неверный размер ключа

AES принимает строго:

  • 16 байт (AES-128)
  • 24 байта (AES-192)
  • 32 байта (AES-256)

Несоответствие приводит к ошибкам или снижению безопасности.


Игнорирование authTag в GCM

Без проверки tag расшифровка теряет смысл:

decipher.getAuthTag(); // обязательно проверять

Работа с бинарными данными

jsrsasign использует hex-представление как основной формат:

var plainHex = KJUR.crypto.Util.utf8tohex("test");
var encryptedHex = cipher.encryptHex(plainHex);

Для обратного преобразования:

var text = KJUR.crypto.Util.hex2utf8(decryptedHex);

Практическая схема использования режимов

CBC — совместимость со старыми системами

  • интеграция с legacy API
  • работа с простыми файлами и архивами

CTR — потоковые данные

  • телеметрия
  • real-time обмен

GCM — современные протоколы

  • JWT encryption
  • API security
  • защищённые каналы передачи

Взаимодействие с другими компонентами jsrsasign

AES часто используется вместе с:

  • KJUR.crypto.Signature (подпись данных)
  • KEYUTIL (управление ключами)
  • KJUR.jws (JWT обработка)

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

var sig = new KJUR.crypto.Signature({ alg: "SHA256withRSA" });
sig.init(privateKey);
sig.updateString(encryptedData);
var signature = sig.sign();

Обработка ошибок и диагностика

Типовые ошибки:

  • неправильный IV length
  • некорректный padding в CBC
  • отсутствующий authTag в GCM
  • несоответствие ключа

Диагностика обычно сводится к проверке входных параметров:

console.log(keyHex.length);
console.log(ivHex.length);

Совместимость с внешними библиотеками

При взаимодействии с OpenSSL, WebCrypto или CryptoJS важно учитывать:

  • различия в padding
  • формат IV (hex vs base64)
  • порядок байтов
  • наличие/отсутствие authTag в GCM

Особенно часто несовместимость возникает в GCM из-за различий в упаковке tag и ciphertext.