Выбор числа итераций в зависимости от контекста

В SJCL параметр итераций напрямую связан с функциями получения ключа из пароля, прежде всего с PBKDF2 (sjcl.misc.pbkdf2). Его роль — искусственно увеличить вычислительную стоимость подбора пароля, делая каждую попытку атакующего дороже по времени и ресурсам.

Итерация в этом контексте — это повторное применение криптографической хэш-функции. Если одна операция хэширования занимает условно 1 единицу времени, то 100 000 итераций превращают её в 100 000 единиц. При этом линейное увеличение параметра почти линейно увеличивает время легитимного вычисления и атаки перебором.

PBKDF2 в SJCL и смысл параметра iterations

Функция PBKDF2 в SJCL выглядит так:

sjcl.misc.pbkdf2(password, salt, iterations, keyLength)

Параметр iterations задаёт число циклов HMAC-SHA256 (или другой выбранной хэш-функции).

Ключевая особенность: каждое увеличение iterations одинаково влияет и на пользователя, и на атакующего. Поэтому выбор значения — это компромисс между безопасностью и удобством.

Модель угроз и влияние числа итераций

Выбор числа итераций определяется не абстрактной “рекомендованной цифрой”, а моделью атаки:

  • Онлайн-атака: ограниченное число попыток, часто итерации играют второстепенную роль
  • Оффлайн-атака: украдена база хэшей → перебор полностью контролируется атакующим

Итерации критически важны именно во втором случае.

Оценка защиты может быть выражена через простую модель:

Стоимость атаки ∝ iterations × стоимость одного PBKDF2

Если атакующий имеет GPU/ASIC-ускорение, выигрыш пользователя от увеличения iterations сохраняется, но не линейно — разрыв уменьшается.

Практические диапазоны значений

Исторически PBKDF2 использовался с очень низкими значениями (1000–10000), что сегодня считается недостаточным.

Современные ориентиры зависят от среды:

Браузер (SJCL client-side)

  • 10 000 – 100 000: минимальный разумный диапазон
  • 100 000 – 300 000: часто используемый баланс
  • 300 000+: возможно, но требует тестирования UX

Основное ограничение — блокировка UI потока JavaScript.

Серверная среда

  • 100 000 – 1 000 000+
  • допустимы высокие значения, если есть масштабирование

Ограничение производительности в браузере

JavaScript выполняется в основном потоке (если не использовать Web Workers). Это означает:

  • слишком высокие iterations → фриз интерфейса
  • пользователь воспринимает систему как “зависшую”
  • возможны таймауты в UI-фреймворках

Практический критерий:

время вычисления PBKDF2 не должно превышать 100–500 мс в клиентском режиме без worker’ов

Поэтому iterations подбирается не только по безопасности, но и по измеренному времени выполнения.

Адаптивный выбор итераций

В SJCL нет автоматического выбора оптимального iterations, поэтому применяется ручная калибровка:

  1. Измеряется время PBKDF2 на целевом устройстве
  2. Выбирается целевое время (например, 200 мс)
  3. Вычисляется iterations под эту задержку

Пример логики:

function calibrate(password, salt) {
    let t0 = performance.now();
    sjcl.misc.pbkdf2(password, salt, 1000);
    let t1 = performance.now();

    let timePerIteration = (t1 - t0) / 1000;
    let targetTime = 200; // ms

    return Math.floor(1000 * (targetTime / timePerIteration));
}

Это упрощённая модель, но она отражает ключевую идею: итерации — это производная от времени, а не фиксированная константа.

Влияние железа атакующего

Важно учитывать, что стоимость одной итерации не одинакова:

  • CPU: медленно, но универсально
  • GPU: параллелизация ускоряет перебор
  • ASIC: максимальная оптимизация хэш-функции

PBKDF2 относительно плохо защищён от GPU, так как не содержит memory-hard компонентов. Поэтому увеличение iterations — это лишь частичная защита.

Сравнение с memory-hard функциями

SJCL также поддерживает scrypt, где параметры заменяют iterations более сложной моделью:

  • N — CPU/memory cost
  • r — block size
  • p — parallelization factor

В отличие от PBKDF2:

  • увеличение iterations увеличивает только время
  • scrypt увеличивает ещё и потребление памяти

Это делает scrypt более устойчивым к GPU-атакам при сопоставимых задержках.

Связь iterations и UX-порогов

На практике вводится два порога:

  • интерактивный режим: 50–200 мс
  • фоновая генерация ключа: до 1–2 секунд

Если превышен интерактивный порог:

  • необходимо использовать Web Worker
  • или снижать iterations
  • или переходить на async-генерацию

Типичные ошибки выбора

  1. Фиксированное маленькое значение (например, 1000) → устаревшая безопасность

  2. Слишком большое значение без теста → зависание браузера

  3. Игнорирование различий устройств → на слабых устройствах деградация UX

  4. Отсутствие обновления параметров со временем → со временем GPU делает атаки дешевле

Практическая стратегия выбора

Выбор iterations в SJCL обычно сводится к следующей логике:

  • определить среднее устройство пользователя
  • измерить производительность PBKDF2
  • задать целевую задержку (100–300 мс)
  • вычислить iterations
  • зафиксировать с запасом 20–30%
  • периодически пересматривать параметр

Долгосрочная деградация безопасности

Со временем вычислительные мощности растут, и фиксированное значение iterations теряет силу. Это приводит к эффекту:

реальная стойкость ∝ iterations / вычислительная мощность атакующего

Поэтому системы, использующие SJCL, должны учитывать необходимость миграции параметров при обновлении данных или смене пароля.

Компромисс между масштабируемостью и безопасностью

Итерации — это линейный регулятор стоимости. Он удобен, но ограничен:

  • легко настраивается
  • плохо адаптируется к GPU/ASIC
  • требует постоянной ревизии

В системах с высокими требованиями к защите обычно комбинируют:

  • PBKDF2 (SJCL)
  • scrypt или Argon2 (внешние реализации)
  • дополнительные server-side задержки

Так формируется многоуровневая модель, где iterations остаются только одной из составляющих стоимости атаки.