Источники энтропии в браузере

В современных браузерах криптографическая стойкость генерации случайных чисел зависит от того, насколько разнообразные и непредсказуемые данные удаётся собрать до момента инициализации генератора. SJCL (Stanford Javascript Crypto Library) строит свою систему поверх комбинации системных и пользовательских источников энтропии, формируя пул случайности, который затем используется для инициализации CSPRNG.

Аппаратный уровень в браузере представлен прежде всего интерфейсом:

window.crypto.getRandomValues()

Этот источник считается базовым и наиболее надёжным. Он опирается на системный генератор операционной системы, который обычно использует аппаратные шумы (timing jitter, thermal noise, hardware RNG инструкции процессора). SJCL при наличии этого API может значительно сократить необходимость в дополнительной энтропии, однако полностью не полагается на него во всех конфигурациях и режимах совместимости.

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


Событийная энтропия пользовательского ввода

Основной пласт дополнительной энтропии в SJCL формируется из пользовательских событий. В браузере эти данные обладают высокой степенью непредсказуемости, особенно при первых взаимодействиях с страницей.

Ключевые источники:

  • движения мыши
  • клики
  • нажатия клавиш
  • события прокрутки
  • касания на мобильных устройствах

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

sjcl.random.addEntropy(data, bits, source)

где:

  • data — числовое значение или массив параметров события
  • bits — оценка энтропии в битах
  • source — идентификатор источника (например, mouse, keyboard)

Модель оценки энтропии консервативна: даже большое количество событий не приводит к линейному росту доверия, так как события пользователя могут быть частично предсказуемыми (например, равномерное движение мыши или автоматизированные скрипты).


Тайминговая энтропия и джиттер исполнения

Отдельный класс источников связан с измерением микроскопических отклонений во времени выполнения JavaScript-кода. Браузер не предоставляет гарантированно точного таймера, а такие функции как:

  • Date.now()
  • performance.now()

имеют вариативную точность в зависимости от устройства, нагрузки и политики защиты от side-channel атак.

SJCL использует различия между ожидаемым и фактическим временем выполнения операций, включая:

  • задержки event loop
  • колебания рендеринга
  • планирование задач в очереди макротасков

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


Инициализация и сбор энтропии в SJCL

Центральный компонент системы — объект sjcl.random, который управляет состоянием пула и состоянием генератора.

Типичная схема инициализации:

sjcl.random.startCollectors();

После вызова библиотека активирует стандартные сборщики:

  • mouse events collector
  • keyboard events collector
  • accelerometer (если доступен)
  • timing collector

Каждый сборщик подписывается на события DOM через addEventListener и начинает накапливать данные в пуле.

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


Проблема холодного старта

Наиболее критичный момент — состояние «холодного старта», когда пользователь ещё не взаимодействовал со страницей. В этот период доступная энтропия минимальна.

SJCL решает эту проблему через комбинацию:

  • window.crypto.getRandomValues() (если доступен)
  • предварительное накопление системных таймерных шумов
  • пассивный сбор событий загрузки страницы

При этом библиотека может находиться в состоянии недостаточной энтропии, возвращая предупреждение через:

sjcl.random.isReady()

или используя уровни готовности:

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

Статистическая модель пула энтропии

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

Например:

  • координаты мыши дают ограниченную энтропию
  • временные интервалы между нажатиями клавиш — более ценны
  • системные вызовы RNG — максимальный вес

Пул затем используется для генерации ключевого материала через AES-базированный PRNG в режиме счётчика. Состояние генератора периодически перемешивается (rekeying), чтобы исключить деградацию энтропии со временем.


Безопасностные ограничения браузерной модели

Браузерная среда накладывает фундаментальные ограничения:

  • отсутствие доступа к физическим шумам устройства
  • возможность наблюдения за паттернами пользовательского поведения
  • потенциальное вмешательство расширений или скриптов

Из-за этого SJCL рассматривает любую событийную энтропию как вспомогательную, а не первичную. Основная криптографическая устойчивость должна обеспечиваться системным генератором ОС, когда он доступен.


Приоритизация источников

При формировании итогового пула энтропии SJCL применяет иерархию доверия:

  1. window.crypto.getRandomValues() — максимальный приоритет
  2. системные таймерные шумы
  3. пользовательские события (мышь, клавиатура)
  4. косвенные браузерные задержки выполнения

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


Практическая модель накопления

В реальной работе библиотека постоянно обновляет пул:

document.addEventListener("mousemove", function (e) {
    sjcl.random.addEntropy([e.clientX, e.clientY], 2, "mouse");
});

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


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

Если пул не достигает требуемого уровня, SJCL может:

  • блокировать генерацию ключей
  • откладывать выполнение криптографических операций
  • использовать fallback на системный RNG

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