В библиотеке SJCL (Stanford JavaScript Crypto Library) генератор
псевдослучайных чисел построен вокруг объекта sjcl.random,
который реализует криптографически стойкий PRNG с накоплением энтропии
из различных источников среды выполнения JavaScript. Основная идея
заключается не в прямом использовании детерминированного алгоритма, а в
постоянном сборе случайности из событий системы и её последующем
преобразовании в ключевой материал через хэш-функции.
sjcl.randomЦентральный элемент генерации случайных чисел — глобальный экземпляр:
sjcl.random
Он представляет собой состояние генератора, включающее:
SJCL не использует один источник случайности. Вместо этого он комбинирует множество слабых источников, превращая их в криптографически устойчивый поток.
Энтропия поступает из событий браузера и окружения:
Каждое событие преобразуется в числовое представление и добавляется в общий пул.
sjcl.random.addEventListener("mousemove");
sjcl.random.addEventListener("keypress");
Фактически библиотека использует не эти строки напрямую, а внутренние
обработчики, подключаемые через addEventListener в
зависимости от среды.
SJCL позволяет вручную вносить данные в пул:
sjcl.random.addEntropy(data, bits, source)
data — исходные данные (число, массив или строка)bits — оценка количества энтропииsource — идентификатор источникаПример:
sjcl.random.addEntropy([123456, 987654], 32, "custom-source");
Ключевой момент — разработчик обязан указать количество бит энтропии. SJCL не пытается самостоятельно оценивать качество входных данных.
Внутренне используется структура пула, в которую складываются данные от разных источников. Эти данные затем смешиваются через хэш-функции (обычно SHA-256 или SHA-512 в зависимости от конфигурации).
Пул не является прямым источником случайных чисел. Он лишь накопитель состояния, которое затем «переплавляется» в ключевой материал.
Генератор SJCL не считается готовым сразу после загрузки. Его состояние определяется уровнем накопленной энтропии:
sjcl.random.isReady()
Возвращаемые значения:
0 — недостаточно энтропии1 — частично готов (можно использовать с
ограничениями)2 — полностью готовДополнительно можно получить уровень:
sjcl.random.getProgress()
Он возвращает число от 0 до 1, отражающее относительный прогресс накопления энтропии.
При загрузке SJCL автоматически подключает стандартные источники энтропии (если включены соответствующие модули). В браузере это обычно:
После накопления минимального объёма данных PRNG переключается в рабочий режим.
В некоторых сценариях требуется форсированная инициализация:
sjcl.random.startCollectors()
Этот метод активирует сборщики энтропии.
Также можно завершить сбор:
sjcl.random.stopCollectors()
Это полезно в средах, где события не предполагаются (например, серверные окружения).
sjcl.random.randomWords(n, paranoia)
n — количество 32-битных словparanoia — уровень требуемой уверенностиПример:
var words = sjcl.random.randomWords(4);
Результат — массив из 32-битных чисел.
Параметр paranoia определяет, сколько энтропии
требуется:
Если энтропии недостаточно, вызов может блокироваться до её накопления.
После накопления энтропии SJCL преобразует её в ключ AES, который используется в режиме CTR (Counter Mode).
Схема:
Это обеспечивает:
Каждое добавление данных в пул приводит к ре-микшированию:
Это предотвращает ситуацию, при которой слабые источники могли бы доминировать в состоянии генератора.
Возможен полный сброс:
sjcl.random.reset()
При этом:
После сброса генератор снова требует накопления энтропии.
Node.js или headless-среды не предоставляют естественных источников событий. В этом случае:
isReady() === 0При недостаточной энтропии SJCL может использовать ограниченный PRNG. Это снижает криптографическую стойкость и требует осторожности при использовании в безопасности-критичных сценариях.
В браузерных условиях качество случайности напрямую связано с активностью пользователя. Без взаимодействия с интерфейсом накопление энтропии замедляется или останавливается.
Генератор SJCL применяется в:
Пример генерации соли:
var salt = sjcl.random.randomWords(4);
PRNG часто используется как источник начальной соли:
var salt = sjcl.random.randomWords(2);
var key = sjcl.misc.pbkdf2(password, salt, 10000, 256);
Здесь качество случайности напрямую влияет на стойкость всей схемы.
Типичный контроль состояния:
if (sjcl.random.isReady() < 2) {
// ожидание накопления энтропии
}
или с прогрессом:
console.log(sjcl.random.getProgress());
Генератор случайных чисел в SJCL не является вспомогательным модулем. Он выполняет фундаментальную роль:
Его безопасность определяет устойчивость всей криптосистемы библиотеки.