Форсированная инициализация PRNG

В основе Stanford JavaScript Crypto Library лежит генератор случайных чисел sjcl.random, реализующий криптографически стойкий PRNG на базе накопления энтропии из множества источников окружения. Его поведение строго разделено на этапы: сбор энтропии, оценка её качества и выдача случайных значений только после достижения порогового уровня уверенности.

Ключевой принцип заключается в том, что генератор не начинает выдавать криптографические значения до тех пор, пока не будет накоплен достаточный объём энтропии, соответствующий выбранному уровню паранойи (paranoia level).

Энтропийная модель и внутренние состояния

Внутреннее состояние sjcl.random основано на пуле энтропии, который пополняется через:

  • события мыши и клавиатуры в браузере
  • тайминги событий (high-resolution timestamps)
  • системные источники (если доступны)
  • ручные вызовы addEntropy
  • встроенные коллекторы энтропии

Каждый источник имеет вес и качество, которые влияют на итоговую оценку безопасности.

Состояние генератора определяется через:

  • 0 — недостаточно энтропии
  • 1 — минимально допустимая готовность
  • 2 — полная готовность для криптографических операций

Природа форсированной инициализации

Форсированная инициализация PRNG в контексте SJCL означает принудительное приведение генератора в состояние готовности в условиях, когда естественные источники энтропии недоступны или недостаточны.

Такие ситуации характерны для:

  • headless окружений
  • серверных Node.js приложений без событийной модели браузера
  • тестовых сред
  • ранней стадии загрузки приложения до накопления событий пользователя

Базовые механизмы управления готовностью

Проверка состояния генератора

(paranoia)

Метод возвращает текущий уровень готовности генератора относительно требуемого уровня паранойи.

Пример:

if (!sjcl.random.isReady(2)) {
    // энтропии недостаточно
}

Запуск сборщиков энтропии

sjcl.random.startCollectors();

Этот вызов активирует стандартные сборщики событий, которые начинают накапливать энтропию из окружения браузера.

В headless или серверной среде эффект ограничен, поскольку отсутствуют пользовательские события.


Ручное добавление энтропии

Одним из ключевых механизмов форсирования является прямое внесение энтропии:

sjcl.random.addEntropy([timestamp, processId, counter], 32, "custom");

Параметры:

  • массив чисел как источник данных
  • количество бит энтропии
  • идентификатор источника

Этот метод часто используется для первичного “разогрева” генератора.


Прогресс готовности

sjcl.random.getProgress(2);

Возвращает число от 0 до 1, отражающее степень накопленной энтропии относительно выбранного уровня паранойи.


Форсирование готовности через seed-стратегии

Временное семя (time seeding)

Наиболее распространённый метод первичного насыщения:

sjcl.random.addEntropy(new Date().getTime(), 32, "time");

Этот подход добавляет базовую энтропию, но сам по себе недостаточен для криптографических целей.


Комбинированное начальное заполнение

sjcl.random.addEntropy([
    Date.now(),
    Math.random() * 1e9,
    performance.now()
], 64, "bootstrap");

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


Проблема серверной среды

В Node.js и аналогичных окружениях отсутствует естественный поток событий, что приводит к следующему поведению:

  • sjcl.random.isReady() долго остаётся 0
  • генерация случайных значений блокируется
  • криптографические операции не могут стартовать

Это фундаментальное ограничение архитектуры SJCL, ориентированной на браузер.


Форсированная инициализация в серверных условиях

В серверных приложениях применяется искусственное насыщение энтропии:

const crypto = require("crypto");

sjcl.random.addEntropy(
    crypto.randomBytes(32).toString("hex"),
    256,
    "node-crypto"
);

Такой подход фактически заменяет отсутствие пользовательских событий системным CSPRNG источником.


Принудительное достижение состояния готовности

Формально SJCL не предусматривает “override” готовности, однако в практических реализациях применяется стратегия ожидания и насыщения:

function ensureReady() {
    while (!sjcl.random.isReady(2)) {
        sjcl.random.addEntropy(Date.now(), 32, "tick");
    }
}

Такой цикл используется только в контролируемых средах, поскольку может приводить к искусственной и некорректной оценке энтропии.


Роль paranoia level

Уровень паранойи определяет минимальный порог энтропии, необходимый для генерации ключей:

  • 0 — минимальная безопасность
  • 1 — стандартный уровень
  • 2 — максимальная криптографическая стойкость

Форсированная инициализация часто направлена на достижение уровня 2 в условиях отсутствия естественных источников данных.


Внутренний механизм блокировки генерации

До достижения нужного уровня готовности вызов:

sjcl.random.randomWords(n)

может:

  • выбрасывать исключение
  • возвращать ограниченные данные
  • блокировать выполнение (в зависимости от конфигурации)

Это предотвращает использование слабого состояния PRNG.


Риски искусственного форсирования

Форсированная инициализация разрушает базовую модель доверия SJCL к источникам энтропии:

  • подмена слабой энтропии на псевдослучайные значения
  • деградация криптографической стойкости
  • предсказуемость выходных данных при плохой seed-стратегии

Особенно критично использование Math.random() как источника, поскольку он не является криптографически стойким генератором.


Практика безопасного bootstrap

Корректный подход в изолированных средах заключается в комбинировании системных источников:

const crypto = require("crypto");

sjcl.random.addEntropy(crypto.randomBytes(64), 512, "crypto");
sjcl.random.addEntropy(Date.now(), 32, "time");

sjcl.random.startCollectors();

Такой подход позволяет перевести генератор в рабочее состояние без нарушения криптографической модели.


Поведение при недостатке энтропии

SJCL сохраняет строгое ограничение:

  • генерация ключей блокируется
  • шифрование не стартует
  • любые криптооперации требуют готовности PRNG

Это делает форсированную инициализацию не просто техническим приёмом, а точкой, определяющей безопасность всей системы.