Cipher Block Chaining (CBC) — один из классических режимов работы блочных шифров, используемых в криптографических библиотеках, включая CryptoJS. Его ключевая особенность заключается в том, что каждый блок открытого текста перед шифрованием комбинируется с предыдущим блоком шифротекста.
Математически это выражается следующим образом:
Шифрование:
[ C_i = E_K(P_i C_{i-1})]
Расшифрование:
[ P_i = D_K(C_i) C_{i-1}]
где:
Главный смысл CBC заключается в том, что одинаковые блоки входных данных при разных позициях дают разные результаты шифрования, что устраняет проблему повторяющихся паттернов.
Первый блок не имеет предыдущего шифротекста, поэтому используется специальное значение — вектор инициализации.
Ключевые свойства IV:
Использование одинакового IV с одним ключом приводит к снижению криптографической стойкости, так как первый блок становится предсказуемым при анализе повторяющихся данных.
В библиотеке CryptoJS режим CBC используется по умолчанию для алгоритма AES.
Пример шифрования:
import CryptoJS from "crypto-js";
const key = CryptoJS.enc.Utf8.parse("1234567890123456");
const iv = CryptoJS.enc.Utf8.parse("abcdef9876543210");
const plaintext = "confidential data";
const encrypted = CryptoJS.AES.encrypt(plaintext, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log(encrypted.toString());
Здесь явно указаны:
const decrypted = CryptoJS.AES.decrypt(encrypted, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log(decrypted.toString(CryptoJS.enc.Utf8));
Расшифрование требует строго тех же параметров:
Несоответствие любого из параметров делает восстановление данных невозможным.
Основной механизм CBC — последовательная зависимость блоков.
При шифровании:
Это создаёт эффект цепи:
Это свойство одновременно является преимуществом и ограничением режима.
Если изменить один бит в шифротексте:
Таким образом влияние ошибки ограничено двумя блоками.
CBC требует, чтобы длина входных данных была кратна размеру блока.
В CryptoJS используется PKCS7 padding:
Принцип работы:
Пример:
"HELLO" (5 байт)
дополняется до 16 байт:
"HELLO\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
При расшифровке padding автоматически удаляется.
CBC считается устаревающим режимом в новых системах, но всё ещё широко используется.
Преимущества:
Недостатки:
CBC сам по себе не защищает от модификации шифротекста. Для этого требуется дополнительный механизм, например HMAC.
Использование одного IV для разных сообщений с одним ключом приводит к раскрытию структуры данных.
Фиксированный IV делает первый блок предсказуемым.
CryptoJS.AES.encrypt("text", "secretkey", {...})
Такой подход приводит к неочевидной генерации ключа и снижает контроль над безопасностью.
CryptoJS возвращает ciphertext в Base64 по умолчанию. Ошибки при преобразовании могут привести к потере данных.
Алгоритм шифрования по блокам:
При расшифровании процесс обратный:
CBC является последовательным режимом:
Это делает его медленнее современных режимов, таких как CTR или GCM, которые допускают параллелизм.
При одинаковом входе:
Эта разница делает CBC значительно более устойчивым к анализу структуры данных.
CBC часто используется:
Однако в новых системах предпочтение отдается режимам, обеспечивающим аутентификацию, например AES-GCM.
Если часть шифротекста повреждена:
Это делает CBC устойчивым к локальным ошибкам передачи данных, но не к целенаправленным атакам.
Типовая конфигурация CBC:
{
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
iv: iv,
key: key
}
Критически важно:
CBC создаёт зависимость между блоками, что влияет на архитектуру систем:
Эти особенности делают CBC менее удобным для современных высоконагруженных систем, но сохраняют его актуальность в сценариях, где важна простота и совместимость.