У статті розбирається підхід Ayesh Karunaratne до використання AEGIS у PHP через розширення Sodium: коли алгоритми доступні, чим відрізняються AEGIS-128L і AEGIS-256 та як їх застосувати на практиці.
Коли AEGIS реально доступний у вашому PHP
AEGIS вбудовано не у всі збірки PHP. Щоб функції AEGIS працювали, потрібні одночасно три умови:
- версія PHP 8.4 або новіша
- розширення Sodium зібране з
libsodiumверсії 1.0.19 або новішої - процесорна архітектура
x86_64абоaarch64(64-бітні CPU, які мають апаратне прискорення AES)
Практичний спосіб перевірити доступність AEGIS — не дивитися на версії, а перевірити наявність конкретної функції Sodium. Наприклад:
if (function_exists('\sodium_crypto_aead_aegis128l_encrypt')) {
// AEGIS available
}
Якщо ця перевірка повертає true, можна спиратися на AEGIS-128L і AEGIS-256. Якщо ні — доведеться залишитися на AES-GCM або CHACHA20-POLY1305.
Що таке AEGIS в контексті PHP Sodium
AEGIS — це сімейство AEAD-алгоритмів (authenticated encryption with associated data) на основі AES. У PHP через Sodium доступні дві реалізації:
AEGIS-128L— ключ 128 біт, nonce 128 бітAEGIS-256— ключ 256 біт, nonce 256 біт
Обидва алгоритми:
- шифрують повідомлення з автентифікацією (перевіряють цілісність і ключ)
- дозволяють додаткові дані (AAD), які не шифруються, але включаються в MAC (наприклад, ID користувача)
- теоретично підтримують довжини даних менше ніж
2^64біт
Важливий нюанс: у Sodium більшість AEAD-алгоритмів використовує 256-бітні ключі. AEGIS-128L — єдиний варіант з 128-бітним ключем, тож не варто намагатися «перевикористати» ключі від інших алгоритмів без явної регенерації.
Оригінальна робота про AEGIS описує внутрішню конструкцію алгоритмів; Ayesh Karunaratne посилається на неї як на джерело теорії.
AEGIS-128L: приклад використання та практичні акценти
AEGIS-128L у PHP зручно використовувати для типових задач симетричного шифрування (наприклад, захист токенів або локально зашифрованих даних користувача). Схема роботи така:
- Генеруємо випадковий ключ довжини 16 байт функцією Sodium
- Генеруємо випадковий nonce фіксованої довжини (16 байт)
- Визначаємо додаткові дані (AAD) — вони можуть бути порожніми
- Шифруємо повідомлення
- Для розшифрування використовуємо ті ж ключ, nonce і AAD
У PHP це виглядає так:
// generate a random key of sufficient length (16 bytes)
// This value must not be public.
$key = sodium_crypto_aead_aegis128l_keygen();
// Generate random nonce value of SODIUM_CRYPTO_AEAD_AEGIS128L_NPUBBYTES length (16 bytes).
// This value should be stored along the encrypted text, but is not required to be private
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_AEGIS128L_NPUBBYTES);
// Additional data. This can be a user ID, email address, or empty.
$additional_data = '';
// Message to encrypt
$message = 'Hello';
// Encrypt
$ciphertext = sodium_crypto_aead_aegis128l_encrypt($message, $additional_data, $nonce, $key);
// Decrypt
$decryptedMessage = sodium_crypto_aead_aegis128l_decrypt($ciphertext, $additional_data, $nonce, $key); // "Hello"
Кілька практичних моментів на основі прикладу:
- Ключ має залишатися конфіденційним. У продакшні його варто зберігати поза репозиторієм коду: в системі керування секретами, в змінних середовища або окремому захищеному сховищі.
- Nonce не обов'язково тримати в секреті, але його необхідно зберегти разом із шифртекстом, щоб потім розшифрувати дані.
- З точки зору безпеки для AEAD-алгоритмів критично не повторювати одну й ту ж пару «ключ + nonce» для різних повідомлень. У прикладі показане випадкове генерування nonce, що підходить для більшості сценаріїв, якщо генератор випадкових чисел криптографічно стійкий.
- Additional data можна використовувати як «прив'язку» шифрування до певного контексту, наприклад до конкретного користувача. Якщо під час дешифрування AAD змінити, функція поверне
false.
AEGIS-256: коли обрати старшого «брата»
AEGIS-256 працює аналогічно, але з ширшим ключем та nonce:
- довжина ключа 32 байти (256 біт)
- довжина nonce задається константою
SODIUM_CRYPTO_AEAD_AEGIS256_NPUBBYTES(32 байти) - допускає ті ж обмеження на загальну довжину даних, що й AEGIS-128L (менше
2^64біт)
Автор зазначає, що AEGIS-256 зазвичай приблизно на 20 % більш обчислювально затратний, ніж AEGIS-128L, якщо не брати до уваги окремі винятки.
Приклад використання виглядає практично так само, як і для AEGIS-128L, але з іншими функціями та константами:
// generate a random key of sufficient length (32 bytes)
// This value must not be public.
$key = sodium_crypto_aead_aegis256_keygen();
// Generate random nonce value of SODIUM_CRYPTO_AEAD_AEGIS128L_NPUBBYTES length (32 bytes).
// This value should be stored along the encrypted text, but is not required to be private
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_AEGIS256_NPUBBYTES);
// Additional data. This can be a user ID, email address, or empty.
$additional_data = '';
// Message to encrypt
$message = 'Hello';
// Encrypt
$ciphertext = sodium_crypto_aead_aegis256_encrypt($message, $additional_data, $nonce, $key);
// Decrypt
$decryptedMessage = sodium_crypto_aead_aegis256_decrypt($ciphertext, $additional_data, $nonce, $key); // "Hello"
З погляду дизайну API це означає:
- можна легко «підмінити» алгоритм в існуючій системі, де вже використовується інший AEAD з Sodium: структура викликів і наявність AAD такі ж
- варто зберігати разом із шифртекстом і nonce ще й ідентифікатор алгоритму, щоб мати змогу надалі міняти алгоритм шифрування без зламу формату даних
Перформанс: де саме AEGIS дає виграш
Ayesh Karunaratne наводить результати бенчмарків AEGIS проти AES-GCM та CHACHA20-POLY1305 на процесорі AMD Ryzen 4800H (x86_64 з AES-NI). Тести охоплюють два сценарії:
- Data rate — шифрування блоку 20 МБ випадкових даних, середнє з 100 ітерацій (без урахування часу генерації ключів і nonce)
- Operations/second — шифрування 1 КБ даних, середнє з 1 000 000 ітерацій (також без RNG-частини)
Зведені результати:
| Algorithm | Data Rate (GB/sec) | Operations/sec |
|---|---|---|
| aes256gcm | 2.31 GB/sec | 1,168,300 ops/sec |
| chacha20poly1305 | 1.29 GB/sec | 738,411 ops/sec |
| chacha20poly1305_ietf | 1.28 GB/sec | 746,409 ops/sec |
| xchacha20poly1305 | 1.28 GB/sec | 692,764 ops/sec |
| aegis128l | 4.99 GB/sec | 1,925,310 ops/sec |
| aegis256 | 4.61 GB/sec | 1,771,924 ops/sec |
З цих цифр випливають кілька практичних висновків саме в рамках наведеного тесту:
- AEGIS-128L приблизно удвічі швидший за AES-GCM за пропускною здатністю (4.99 проти 2.31 GB/сек)
- AEGIS-256 дещо повільніший за AEGIS-128L, але все одно помітно швидший за AES-GCM
- обидва варіанти AEGIS у кілька разів випереджають CHACHA20-POLY1305 у цих умовах
- AEGIS-алгоритми виконують більш ніж удвічі більше операцій шифрування 1 КБ за секунду порівняно з AES-GCM
Автор окремо наголошує на контексті: усі AES-алгоритми (включно з AEGIS) на процесорах з підтримкою AES-NI працюють значно швидше. Натомість на слабких мобільних та вбудованих пристроях, які не мають AES-NI, перевага може бути іншою. Більшість серверів, на яких запускають PHP, близькі до умов бенчмарків або здатні досягати подібних швидкостей.
Як інтегрувати AEGIS у існуючий PHP-проєкт
Окремо від синтаксису функцій, зручно врахувати таку практичну схему:
- На старті додатку перевірити, чи доступний AEGIS (як у прикладі з
function_exists). - Якщо AEGIS є, обрати базовим алгоритмом
AEGIS-128LабоAEGIS-256(залежно від політики безпеки та вимог до швидкості). - У форматі збереження шифртексту додати поле «algorithm», щоб підтримати подальшу міграцію.
- Організувати централізований сервіс шифрування, який ховає від бізнес-логіки деталі ключів, nonce та вибору алгоритму.
Підхід, описаний Ayesh Karunaratne, дає зрозумілий базовий шаблон для роботи з AEGIS у PHP 8.4: окремі функції для кожного алгоритму, явна робота з nonce та додатковими даними й можливість отримати суттєвий виграш у швидкості на сучасних серверних CPU.
Ілюстрації з оригіналу

Джерело: Ayesh Karunaratne — PHP.Watch: статьи