Режимы шифрования AES объяснены Почему GCM превосходит CBC в большинстве случаев (и когда это не так)
AES сам по себе не является полным выбором алгоритма. Режим — CBC, CTR, GCM, ECB — определяет всё о том, безопасна ли ваша шифровка. Ниже — практическое объяснение, которое нужны разработчикам.
Когда документация говорит вам «использовать AES-256», это неполное руководство. AES — это блочный шифр — он шифрует ровно один блок из 128 бит за раз. Режим работы определяет, как AES обрабатывает данные длиной более 16 байт, и насколько он защищает вас от атакующих, которые могут наблюдать или вмешиваться в шифрованные данные. Ошибки в этом аспекте приводят к тому, что «зашифрованные» данные утечивают структуру файлов или система уязвима к атакам с изменением битов. режим работы определяет, как AES обрабатывает реальные данные длиной более 16 байт, и насколько он защищает вас от атакующих, которые могут наблюдать или вмешиваться в шифрованные данные. Ошибки в этом аспекте приводят к тому, что «зашифрованные» данные утечивают структуру файлов или система уязвима к атакам с изменением битов.
Полный алгоритм описывается так AES-256-GCM или AES-128-CBC — размер ключа, за которым следует режим. В этой статье описано, что делает каждый режим, почему GCM является правильным стандартом по умолчанию, и в каких случаях вы можете законно выбрать что-то иное.
Во-первых, почему ECB — это мем, а не просто шутка
ECB (Electronic Codebook) — это простой режим. Каждый блок из 16 байт исходных данных шифруется независимо с использованием одного и того же ключа. Это означает, что одинаковые блоки исходных данных дают одинаковые блоки шифрованных данных.
Классическим примером является шифрование Linux-пингвина (Tux). Изображение шифруется блоками, но поскольку большие участки изображения имеют единый цвет, в шифрованном виде всё ещё остаётся очевидной форма пингвина. Шифрование математически корректно — данные перемешаны — но паттерн сохраняется.
На практике это важно каждый раз, когда в исходных данных есть повторения: строки базы данных с общим префиксом, заголовки файлов, заполненные поля. ECB раскрывает структуру. Нет законных случаев использования ECB в новых программах. Если вы поддерживаете код, использующий ECB: замените его.
Режимы, которые стоит знать
CBC — режим, который используется большинством устаревших систем
Шифрование блоков цепочкой (CBC) XOR-шифрует каждый блок исходных данных с предыдущим блоком шифрованного текста перед шифрованием. Это решает проблему паттерна ECB — одинаковые блоки исходных данных дают разные блоки шифрованного текста, потому что цепочка делает шифрование каждого блока зависеть от предыдущего блока.
CBC требует вектора инициализации (IV) — случайного значения из 16 байт, которое инициализирует цепочку для первого блока. IV не должен быть секретным, но он должен быть случайным и передаваться вместе с шифрованным текстом.
Проблема с CBC: предоставляет конфиденциальность но не целостность. Атакующий, который может изменять шифрованный текст в процессе передачи, может изменять конкретные биты в расшифрованном выводе по предсказуемым правилам. Это основа атак с паддингом, которые уже сломали реальные системы (POODLE, BEAST, Lucky Thirteen). Если вы используете CBC без отдельного MAC (Message Authentication Code) для проверки целостности, вы уязвимы. Паттерн называется «шифрование-затем-MAC» — сначала шифруем, затем HMAC-шифруем шифрованный текст, затем проверяем MAC перед расшифровкой. Ошибка в порядке выполнения — классическая ошибка.
CBC также является последовательным — вы не можете параллелизировать шифрование (каждый блок зависит от предыдущего шифрованного блока), а расшифровка может быть только частично параллелизируема.
CTR — поведение потокового шифра, основанное на блочном шифре
Режим CTR превращает AES в потоковый шифр. Вместо прямого шифрования исходных данных, он шифрует последовательные значения счётчика и XOR-шифрует результат с исходными данными. Это означает, что режим CTR не требует заполнения (он работает с данными любой длины), полностью параллелизируем в обоих направлениях, и позволяет произвольный доступ к любому месту в шифрованном тексте при расшифровке.
CTR использует nonce (число, используемое один раз), а не полный IV. Нонс должен быть уникальным для каждого сообщения при заданном ключе — повторное использование nonce с тем же ключом раскрывает XOR двух исходных данных, что является катастрофой. В отличие от CBC, CTR также не обеспечивает защиту целостности. Та же история: требуется шифрование-затем-MAC, если вы хотите защиту от вмешательства.
CTR подходит, когда вам нужно свойство потокового шифра — большие файлы, расшифровка с произвольным доступом, высокая производительность в сценариях, где важна параллельность — и вы обрабатываете слой MAC отдельно.
GCM — аутентифицированное шифрование, один шаг
Режим Galois/Counter (GCM) — это CTR с встроенной меткой аутентификации (GHASH). Вы получаете конфиденциальность и целостность в одном примитиве. Метка аутентификации — обычно 128 бит — позволяет получателю проверить, что шифрованный текст не был изменён, до расшифровки. Нет отдельного шага HMAC, нет шанса ошибиться в порядке шифрования-затем-MAC.
GCM также поддерживает Дополнительные аутентифицированные данные (AAD) — данные, которые подтверждаются, но не шифруются. Это полезно для заголовков, метаданных или любых данных, которым нужна защита целостности, но не требуется конфиденциальность. Данные AAD проверяются вместе с шифрованным текстом на метке аутентификации.
Нонс для GCM по умолчанию составляет 96 бит (12 байт). Как и в случае с CTR, повторное использование нонса с тем же ключом приводит к полному нарушению безопасности — раскрываются как сама исходная информация, так и ключ аутентификации (H). Всегда генерируйте нонсы с помощью криптографически безопасного генератора случайных чисел; никогда не вычисляйте их из последовательных счётчиков, если вы не используете тщательно управляемый глобальный счётчик с жёсткими гарантиями уникальности.
GCM является параллелизуемым и не требует заполнения. Это рекомендация по умолчанию в TLS 1.3, Signal Protocol и большинстве современных криптографических библиотек. Если вы пишете новый код, GCM — ваш выбор по умолчанию.
Сравнение режимов
| Режим | Авторизованный | Параллелизуемый | Требует заполнения | Риск повторного использования нонса/IV | Вердикт |
|---|---|---|---|---|---|
| ECB | Нет | Да | Да | Н/Д (нет IV) | Никогда не использовать |
| CBC | Нет (добавить MAC) | Шифрование: Нет / Расшифровка: Да | Да | Умеренный | Устаревший только |
| CTR | Нет (добавить MAC) | Да | Нет | Критично — повторное использование приводит к утечке исходных данных | Ограниченное применение |
| GCM | Да (встроено) | Да | Нет | Критично — повторное использование приводит к полному нарушению безопасности | Стандартный выбор |
AES-256-GCM в Node.js
Вот полная реализация шифрования и расшифровки с использованием встроенной библиотеки Node.js — без необходимости в зависимостях: crypto Несколько моментов, на которые стоит обратить внимание в этом коде:
const crypto = require('crypto');
const ALGORITHM = 'aes-256-gcm';
const KEY_LENGTH = 32; // 256 bits
const NONCE_LENGTH = 12; // 96 bits — GCM default
const TAG_LENGTH = 16; // 128-bit auth tag
function encrypt(plaintext, key) {
const nonce = crypto.randomBytes(NONCE_LENGTH);
const cipher = crypto.createCipheriv(ALGORITHM, key, nonce, {
authTagLength: TAG_LENGTH,
});
const encrypted = Buffer.concat([
cipher.update(plaintext, 'utf8'),
cipher.final(),
]);
const tag = cipher.getAuthTag();
// Prepend nonce + tag to ciphertext for storage/transmission
return Buffer.concat([nonce, tag, encrypted]);
}
function decrypt(ciphertext, key) {
const nonce = ciphertext.subarray(0, NONCE_LENGTH);
const tag = ciphertext.subarray(NONCE_LENGTH, NONCE_LENGTH + TAG_LENGTH);
const data = ciphertext.subarray(NONCE_LENGTH + TAG_LENGTH);
const decipher = crypto.createDecipheriv(ALGORITHM, key, nonce, {
authTagLength: TAG_LENGTH,
});
decipher.setAuthTag(tag);
// Throws if auth tag doesn't match — do not catch this silently
return Buffer.concat([decipher.update(data), decipher.final()]).toString('utf8');
}
// Generate a key (do this once; store it securely)
const key = crypto.randomBytes(KEY_LENGTH);
const message = 'Hello, authenticated encryption.';
const ciphertext = encrypt(message, key);
console.log('Encrypted:', ciphertext.toString('hex'));
const plaintext = decrypt(ciphertext, key);
console.log('Decrypted:', plaintext); // Hello, authenticated encryption.
Нонс генерируется свежим на каждом вызове шифрования
- является криптографически безопасным. Не заменяйте его на счётчик, если вы не понимаете проблемы распределённой уникальности. —
crypto.randomBytesНонс и метка аутентификации хранятся вместе с шифрованным текстом - — они должны передаваться вместе с зашифрованными данными. Нонс является публичным; метка — публичной. Только ключ является секретным. выбрасывает при неудаче проверки аутентичности
decipher.final()— это корректное поведение. Не поймите и возвращайте частичный текст. Неудача проверки аутентичности означает, что данные были изменены или ключ неверен. Управление ключами — сложная часть- предоставляет вам хороший ключ, но то, где вы его храните и как вы его обновляете, имеет большее значение, чем выбор алгоритма. Используйте менеджер секретов, а не константу, встроенную в код. —
crypto.randomBytes(32)Хотите тестировать режимы шифрования интерактивно?
IO Tools’ инструмент шифрования/расшифровки AES позволяет шифровать и расшифровывать с использованием режимов CBC и GCM прямо в браузере — полезно для проверки совместимости или отладки интеграции. Для генерации криптографически безопасного ключа из 256 бит используйте Генератор ключа AES IV и нонс: правила, которые действительно важны.
Неправильное использование нонса/IV приводит к большему количеству реальных нарушений, чем выбор алгоритма. Правила:
Всегда генерируйте нонсы/IV с помощью CSPRNG
- в Node, —
crypto.randomBytes()в Java. Неos.urandom()в Node.js все требуют одинаковое время независимо от того, где строки отличаются. Используйте их каждый раз при сравнении подписи — без исключений.SecureRandom. Не временная метка. Не инкрементирующий счётчик, если он не является правильно управляемым глобальным счётчиком с жёсткими гарантиями уникальности.Math.random()Повторное использование нонса в GCM приводит к полному нарушению аутентификации - — при одинаковом ключе и нонсе GCM раскрывает ключ аутентификации H. Атакующий может затем создавать аутентичные метки для любых шифрованных данных. Это не теоретическая проблема: атака Forbidden использует это и применялась к реальным реализациям. Повторное использование IV в CBC менее катастрофично, но всё равно плохое
- — возможны атаки на выбранное сообщение. На практике всегда генерируйте новый IV для каждого сообщения. Никогда не вычисляйте нонс из содержимого сообщения
- — детерминированные нонсы, зависящие от предсказуемых данных, создают предсказуемые паттерны. Используйте случайность. Когда CBC или CTR всё ещё являются правильным выбором
GCM не всегда является правильным решением:
Совместимость с устаревшими системами
- — если вы интегрируетесь с системой, которая использует только AES-CBC, вы используете CBC. Чётко документируйте требования к MAC и правильно реализуйте их (шифрование-затем-MAC с HMAC-SHA256). Ограниченные среды без аппаратной поддержки GHASH
- — шаг аутентификации GCM использует GHASH, который более трудоёмок, чем простое блочное шифрование на аппаратных платформах без специальной ускоренной поддержки. В некоторых встраиваемых системах, где доступно CTR+CMAC, но нет GHASH, может быть оправдано использование режима CTR. Потоковое шифрование очень больших файлов, где требуется расшифровка с произвольным доступом
- — свойство произвольного доступа CTR полезно, когда нужно расшифровать позицию N без чтения позиций от 0 до N-1. GCM теоретически позволяет это, но проверка метки аутентификации требует обработки всего шифрованного текста, что противоречит цели. Шифрование диска
- — полное шифрование диска использует режим XTS (не охваченный здесь), а не GCM, потому что XTS разработан для фиксированных секторов с произвольным доступом. GCM предназначен для шифрования сообщений, а не секторов. AES-256-GCM
Краткий вариант
Используйте для новых программ. Генерируйте свежий 12-байтовый случайный нонс на каждом вызове шифрования. Храните нонс и метку аутентификации вместе с шифрованным текстом. Трактуйте неудачи проверки аутентичности как ошибки, а не как предупреждения — никогда не возвращайте текст при том, что GCM говорит о его недействительности. Если вы проводите аудит существующего кода CBC: убедитесь, что реализовано правильное шифрование-затем-MAC, проверьте, что IV-значения случайны (не повторяются, не последовательны), и разработайте план миграции на GCM в течение доступного периода обслуживания. CBC с правильным HMAC не сломан — он просто имеет больше «ловушек», чем GCM.
ECB: просто замените его. Нет пути аудита, который бы завершился фразой «ECB здесь допустим».
AES Encryption Modes Explained: Why GCM Beats CBC in Most Cases (and When It Doesn’t) 2
Установите наши расширения
Добавьте инструменты ввода-вывода в свой любимый браузер для мгновенного доступа и более быстрого поиска
恵 Табло результатов прибыло!
Табло результатов — это интересный способ следить за вашими играми, все данные хранятся в вашем браузере. Скоро появятся новые функции!
Подписаться на новости
все Новые поступления
всеОбновлять: Наш последний инструмент was added on Июн 26, 2026
