Криптографическая стойкость алгоритмов симметричного шифрования напрямую связана с длиной ключа, однако влияние этого параметра на производительность часто оказывается менее интуитивным, чем принято считать. В контексте Stanford JavaScript Crypto Library (SJCL) ключевой вопрос заключается в том, как увеличение длины ключа AES с 128 до 192 и 256 бит отражается на скорости операций шифрования и расшифрования.
SJCL реализует AES как блочный шифр с фиксированным размером блока 128 бит, независимо от длины ключа. Поддерживаются три основных варианта:
Важно понимать, что размер блока остаётся неизменным, а различие затрагивает исключительно процедуру расширения ключа (key schedule) и количество раундов шифрования.
Именно число раундов является ключевым фактором, влияющим на производительность.
Перед началом шифрования SJCL выполняет процедуру расширения ключа. Это преобразование исходного ключа в набор раундовых ключей, которые используются на каждом этапе AES.
Увеличение длины ключа приводит к следующим изменениям:
Пример создания AES-контекста в SJCL:
import sjcl from 'sjcl';
const key128 = sjcl.codec.hex.toBits('00112233445566778899aabbccddeeff');
const key256 = sjcl.codec.hex.toBits('00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff');
const aes128 = new sjcl.cipher.aes(key128);
const aes256 = new sjcl.cipher.aes(key256);
На этапе new sjcl.cipher.aes(...) происходит основная
разница в стоимости между вариантами.
С точки зрения вычислительной сложности:
Однако важно учитывать, что key schedule выполняется один раз при инициализации объекта шифра. При многократном шифровании данных одним и тем же ключом эта стоимость становится пренебрежимой.
После инициализации ключа основная работа приходится на сами раунды AES. Каждый раунд включает:
Количество раундов напрямую зависит от длины ключа, поэтому влияние на производительность проявляется линейно.
Если обозначить стоимость одного раунда как T, то:
Разница между AES-128 и AES-256 составляет примерно 40% по количеству раундовых операций, что теоретически должно отражаться на скорости.
SJCL оптимизирован под JavaScript-окружение и использует следующие подходы:
Это приводит к тому, что реальная разница между длинами ключей часто оказывается меньше теоретической.
Причины сглаживания различий:
При массовом шифровании данных (например, потоковые операции) наблюдается следующая картина:
Разница чаще всего находится в диапазоне:
Эти значения зависят от:
В SJCL часто используются режимы:
CTR обычно быстрее CBC, потому что:
При увеличении длины ключа разница между режимами сохраняется, но абсолютная стоимость возрастает одинаково.
const plaintext = sjcl.codec.utf8String.toBits("A".repeat(1024));
function benchmark(cipher, iterations = 1000) {
const start = performance.now();
for (let i = 0; i < iterations; i++) {
cipher.encrypt(plaintext);
}
return performance.now() - start;
}
const aes128 = new sjcl.cipher.aes(key128);
const aes256 = new sjcl.cipher.aes(key256);
console.log(benchmark(aes128));
console.log(benchmark(aes256));
В подобных тестах основная разница проявляется при большом числе итераций, а не при единичных вызовах.
Увеличение длины ключа даёт экспоненциальный рост стойкости к перебору, но линейное ухудшение производительности.
Ключевые соотношения:
При этом в SJCL переход на более длинный ключ не меняет архитектуру шифра, а только увеличивает вычислительную нагрузку на раунды и расширение ключа.
На практике производительность дополнительно зависит от:
Иногда AES-256 может выполняться почти так же быстро, как AES-128, если движок хорошо оптимизирует циклы раундов, однако это скорее исключение, чем правило.
Увеличение длины ключа в SJCL влияет на производительность по двум направлениям:
Первый фактор важен при редком создании объектов шифра, второй — при массовой обработке данных и является определяющим.
В реальных JavaScript-приложениях основное влияние длины ключа проявляется не как критическое замедление, а как умеренное линейное снижение пропускной способности при сохранении одинаковой структуры алгоритма AES.