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

> Шифрование, при котором один и тот же секретный ключ используется для зашифрования и расшифрования; современные алгоритмы AES и ChaCha20 в режимах аутентифицированного шифрования.

Источник: https://llmdocs.ru/wiki/symmetric-encryption/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Принцип**: общий секретный ключ у отправителя и получателя
- **Основные алгоритмы**: AES (128/192/256 бит), ChaCha20
- **Режимы**: GCM, CTR, CBC (устаревающий), XTS (диски)
- **Аутентифицированное шифрование**: AES-GCM, ChaCha20-Poly1305
- **Устаревшие**: DES, 3DES, RC4
- **Российские стандарты**: «Кузнечик», «Магма» (ГОСТ Р 34.12-2015)
**Симметричное шифрование** — класс алгоритмов, в которых один и тот же секретный ключ используется и для зашифрования, и для расшифрования данных. Оно на порядки быстрее [асимметричного](https://llmdocs.ru/wiki/public-key-cryptography.md) и поэтому шифрует практически весь реальный трафик и хранимые данные: в [TLS](https://llmdocs.ru/wiki/tls.md) и [SSH](https://llmdocs.ru/wiki/ssh.md) асимметричная криптография лишь договаривается об общем ключе, а дальше данные шифруются симметрично. Сегодняшние стандарты — **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, устойчивый к повторам.

```python
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)](https://llmdocs.ru/wiki/password-storage.md)). Хранение и ротация ключей — отдельная задача [управления секретами](https://llmdocs.ru/wiki/secrets-management.md).

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

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

## См. также

- [Криптография с открытым ключом](https://llmdocs.ru/wiki/public-key-cryptography.md)
- [Хеш-функция](https://llmdocs.ru/wiki/hash-function.md)
- [TLS](https://llmdocs.ru/wiki/tls.md)
- [Управление секретами](https://llmdocs.ru/wiki/secrets-management.md)
- [SSH](https://llmdocs.ru/wiki/ssh.md)

## Источники

1. [NIST FIPS 197 — Advanced Encryption Standard (AES)](https://csrc.nist.gov/pubs/fips/197/final)
2. [RFC 8439 — ChaCha20 and Poly1305 for IETF Protocols](https://www.rfc-editor.org/rfc/rfc8439)
3. [NIST SP 800-38D — Galois/Counter Mode (GCM)](https://csrc.nist.gov/pubs/sp/800/38/d/final)
4. [RFC 5116 — An Interface and Algorithms for Authenticated Encryption](https://www.rfc-editor.org/rfc/rfc5116)
5. [libsodium — документация](https://doc.libsodium.org/)
6. [Python cryptography — AEAD](https://cryptography.io/en/latest/hazmat/primitives/aead/)
7. [RFC 7801 — GOST R 34.12-2015: Block Cipher Kuznyechik](https://www.rfc-editor.org/rfc/rfc7801)
