Симметричное шифрование (AES, ChaCha20)

Материал из llmdocs — справочник разработчика
Симметричное шифрование (AES, ChaCha20)
Принципобщий секретный ключ у отправителя и получателя
Основные алгоритмыAES (128/192/256 бит), ChaCha20
РежимыGCM, CTR, CBC (устаревающий), XTS (диски)
Аутентифицированное шифрованиеAES-GCM, ChaCha20-Poly1305
УстаревшиеDES, 3DES, RC4
Российские стандарты«Кузнечик», «Магма» (ГОСТ Р 34.12-2015)

Симметричное шифрование — класс алгоритмов, в которых один и тот же секретный ключ используется и для зашифрования, и для расшифрования данных. Оно на порядки быстрее асимметричного и поэтому шифрует практически весь реальный трафик и хранимые данные: в TLS и SSH асимметричная криптография лишь договаривается об общем ключе, а дальше данные шифруются симметрично. Сегодняшние стандарты — AES и ChaCha20, применяемые в режимах аутентифицированного шифрования (AEAD), которые одновременно скрывают содержимое и обнаруживают подделку.[4]

История

Стандарт DES (1977) с 56-битным ключом к концу 1990-х стал уязвим к перебору — в 1998 году специальная машина взломала его за 56 часов. Временной заменой служил 3DES. В 1997 году NIST объявил открытый конкурс, победителем которого в 2000 году стал алгоритм Rijndael бельгийских криптографов Йоана Дамена и Винсента Рэймена; в 2001 году он был утверждён как AES.[1] ChaCha20 — потоковый шифр Дэниела Бернстайна (2008), вместе с кодом аутентификации Poly1305 стандартизированный IETF и вошедший в TLS 1.3.[2] Потоковый шифр RC4, долго применявшийся в SSL и Wi-Fi (WEP), запрещён из-за статистических слабостей.

Блочные и потоковые шифры

  • Блочный шифр (AES) преобразует блок фиксированного размера — 128 бит — под управлением ключа. Чтобы шифровать данные произвольной длины, нужен режим работы.
  • Потоковый шифр (ChaCha20) генерирует из ключа и одноразового числа (nonce) псевдослучайную гамму, которая складывается с данными по XOR.

Режимы работы

Режим Свойства Применение
ECB одинаковые блоки дают одинаковый шифртекст не использовать
CBC цепочка блоков, нужен случайный IV и отдельный MAC устаревшие системы
CTR блочный шифр как потоковый основа GCM
GCM CTR + аутентификация (GHASH) TLS, IPsec, большинство API[3]
XTS шифрование секторов диска FileVault, BitLocker, LUKS

Классическая иллюстрация опасности ECB — зашифрованное изображение, на котором по-прежнему видны контуры исходной картинки.

Аутентифицированное шифрование

Шифрование без проверки целостности опасно: злоумышленник может менять шифртекст, и в ряде режимов это предсказуемо меняет расшифрованные данные или даёт атаку через сообщения об ошибках (padding oracle). AEAD (authenticated encryption with associated data) объединяет шифрование и код аутентификации и позволяет защитить от подделки также незашифрованные «связанные данные» — например, заголовки пакета.[4]

  • AES-GCM — очень быстр на процессорах с аппаратными инструкциями AES-NI (практически все современные x86 и ARM).
  • ChaCha20-Poly1305 — быстр в программной реализации, безопаснее на устройствах без аппаратного AES и менее подвержен атакам по времени; предпочтителен на мобильных и встроенных системах.

Одноразовые числа

Оба AEAD требуют nonce (обычно 96 бит), который никогда не должен повторяться с тем же ключом. Повтор nonce в GCM катастрофичен: раскрывает XOR открытых текстов и позволяет подделывать сообщения. Решения: счётчик, случайный nonce при умеренном числе сообщений на ключ, или варианты с увеличенным nonce — XChaCha20-Poly1305 (192 бита) и AES-GCM-SIV, устойчивый к повторам.

from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
import os

key = ChaCha20Poly1305.generate_key()        # 256 бит
aead = ChaCha20Poly1305(key)
nonce = os.urandom(12)
ct = aead.encrypt(nonce, b"secret message", b"header-v1")
pt = aead.decrypt(nonce, ct, b"header-v1")   # исключение при подделке

Высокоуровневые библиотеки вроде libsodium (crypto_secretbox, crypto_aead_xchacha20poly1305) и Fernet в Python выбирают алгоритм и nonce за программиста — это предпочтительнее, чем собирать конструкцию из примитивов самому.[5][6]

Длина ключа

AES-128 по-прежнему считается стойким; AES-256 и ChaCha20 (256 бит) выбирают с запасом, в том числе на случай квантовых компьютеров: алгоритм Гровера сокращает стойкость перебора примерно вдвое по битам, так что 256-битный ключ остаётся надёжным. Ключи генерируют криптографически стойким генератором, а из паролей выводят специальными функциями (Argon2, scrypt; см. Хранение паролей (bcrypt, Argon2)). Хранение и ротация ключей — отдельная задача управления секретами.

Российские стандарты

ГОСТ Р 34.12-2015 определяет блочные шифры «Кузнечик» (128-битный блок) и «Магма» (64-битный блок, наследник ГОСТ 28147-89) с 256-битным ключом.[7] Они обязательны в ряде государственных систем и поддерживаются в отечественных сборках OpenSSL и TLS.

См. также

Источники

  1. NIST FIPS 197 — Advanced Encryption Standard (AES)
  2. RFC 8439 — ChaCha20 and Poly1305 for IETF Protocols
  3. NIST SP 800-38D — Galois/Counter Mode (GCM)
  4. RFC 5116 — An Interface and Algorithms for Authenticated Encryption
  5. libsodium — документация
  6. Python cryptography — AEAD
  7. RFC 7801 — GOST R 34.12-2015: Block Cipher Kuznyechik