AES-GCM или ChaCha20-Poly1305: выбор шифра данных для VPN
AES-GCM — очевидный выбор на серверах с аппаратным ускорением, а ChaCha20-Poly1305 хорошо работает без него. Возможно, ваш протокол решит за вас.
Оба названия — это конструкции AEAD, обе стандартизованы, и на современном сервере x86 любая из них насытит гигабитный канал без заметных усилий. Выбор перестаёт быть произвольным, когда вы уходите с такого сервера: дешёвые маршрутизаторы, старые телефоны и виртуальные устройства часто не имеют аппаратного ускорения AES, и там разница велика. Поэтому сравнение не в том, какой шифр быстрее, а в том, какой шифр хорошо работает на этом наборе конечных точек и предлагает ли протокол выбор вообще.
Та же работа, другие ядра
Обе конструкции дают конфиденциальность и целостность за один проход и аутентифицируют связанные данные, поэтому протоколы VPN используют их для канала данных. Разница внутри: AES-GCM — это блочный шифр AES в режиме счётчика с полиномиальным аутентификатором над GF(2^128), а ChaCha20-Poly1305 — потоковый шифр с 256-битным ключом и отдельным одноразовым аутентификатором.
То, что важно эксплуатационно, общее: оба катастрофически отказывают при повторном использовании nonce, обоим нужно управление пространством nonce для каждого ключа, и ни один не исправляет партнёра, который аутентифицирует не то. Профиль, где написано AES-256-GCM, не безопаснее профиля с CHACHA20-POLY1305; оба сильны, когда реализация корректна.
Где выигрывает AES-GCM
У AES есть выделенные инструкции на большинстве современных процессоров: AES-NI на x86, криптографические расширения на ARMv8 и аналоги в новых разработках POWER и RISC-V. Когда они есть, GCM обрабатывает несколько блоков параллельно за класс цикла, и программная реализация перестаёт иметь значение. Это обычный случай для серверов, настольных компьютеров и нынешних телефонов, и поэтому совет использовать AES — разумное значение по умолчанию в центре обработки данных.
Проблема — случай второго порядка. Без выделенных инструкций AES в программном обеспечении медленный, а реализации на таблицах имеют долгую историю проблем со временем доступа к кешу. Концентратор VPN в виртуальной машине, чей хост не показывает гостю флаги AES, — ровно этот случай, и его легко упустить, потому что у процессора хоста такая возможность есть.
Проверяйте, что процесс видит на самом деле, а не что поддерживает процессор: grep -o aes /proc/cpuinfo | head -1 в Linux или соответствующий флаг возможности в модели процессора гипервизора.
Где выигрывает ChaCha20-Poly1305
ChaCha20 быстр в переносимом программном обеспечении, потому что использует только сложение, вращение и XOR, а его реализации по устройству избегают поиска по таблицам, зависящего от секрета. На устройстве без ускорения AES это существенное преимущество, и именно поэтому WireGuard выбрал его: описание протокола WireGuard указывает ChaCha20-Poly1305 как шифр данных без альтернативы.
Этот единственный выбор говорит кое-что полезное: на оборудовании с ускорением AES WireGuard уступает часть пропускной способности по сравнению с AES-GCM, и авторы приняли это в обмен на предсказуемое поведение на телефонах, домашних маршрутизаторах и хостах контейнеров. Если ваш парк — в основном небольшие коробки ARM, этот обмен в вашу пользу.
Обратный случай — загруженный концентратор x86, где AES-GCM с AES-NI быстрее и лучше поддержан, а ChaCha20 стоит измеримого процессорного времени на каждый гигабит. Ни одна из конструкций не является слабостью; вопрос в том, какую ваше оборудование выполняет дешевле.
Что ваш протокол действительно позволяет выбрать
| Protocol | What you get |
|---|---|
| WireGuard | ChaCha20-Poly1305 only; no negotiation |
| OpenVPN 2.5 and later | Data channel negotiated from data-ciphers: AES-256-GCM, AES-128-GCM, CHACHA20-POLY1305 |
| IPsec / IKEv2 | AES-GCM as a combined-mode transform, or ChaCha20-Poly1305 where both peers implement it |
| OpenVPN control channel | TLS decides; TLS 1.3 offers AES-GCM and ChaCha20-Poly1305 suites |
Обратите внимание на разделение в OpenVPN: канал управления и канал данных согласуются отдельно, поэтому набор, который вы видите для TLS, ничего не говорит о шифре, защищающем полезную нагрузку. Сводка сеанса сообщает об обоих, и читать только один из двух — обычный источник путаницы.
В OpenVPN шифр канала данных берётся из списка data-ciphers на обоих концах. Если список сервера и список клиента не пересекаются, соединение либо откатывается к тому, что разрешает data-ciphers-fallback, либо полностью падает, и эту ошибку обычно относят к неверному уровню. Задайте один и тот же список с обеих сторон, а затем подтвердите согласованный результат в журнале, вместо того чтобы предполагать, что порядок списка соблюдён.
Решайте по трём фактам о развёртывании
Во-первых, есть ли у конечных точек ускорение AES? Если есть у каждого партнёра, AES-GCM — более дешёвый выбор и значение по умолчанию в большинстве поддерживаемых конфигураций. Если значительная доля — небольшие маршрутизаторы или старые телефоны, ChaCha20-Poly1305 не даёт хвосту парка стать пределом ёмкости.
Во-вторых, предлагает ли протокол выбор вообще? С WireGuard решение уже принято за вас, и полезная работа — убедиться, что инструменты вокруг него не подменяют молча что-то другое. С OpenVPN и IPsec ответ — строка конфигурации и согласованный результат, который нужно записать.
В-третьих, могут ли обе стороны договориться? Шифр, который один партнёр не реализует, — это не решение о производительности, а простой. Поэтому список партнёров важнее любого бенчмарка: смешанному парку нужно пересечение возможностей, а не предпочтение самой быстрой машины.
Если вы измеряете, держите устройство, конечную точку и нагрузку одинаковыми и меняйте одну вещь. Тест, сравнивающий два сервера в разных регионах, измеряет маршрут, а не шифр, а замер на ноутбуке ничего не говорит о хосте контейнеров, чьи флаги процессора скрыты. Сравните, а затем запишите, какой шифр был фактически согласован: эта запись ценнее бенчмарка.