В библиотеке SJCL генератор псевдослучайных чисел (PRNG) реализован как криптографически стойкая система, построенная вокруг потокового шифра и механизма накопления энтропии. Архитектура ориентирована на работу в среде браузера, где отсутствуют гарантированные источники качественной случайности, и потому особое внимание уделяется сбору и оценке энтропии.
PRNG в SJCL представлен объектом sjcl.prng, который
управляет внутренним состоянием, пулами энтропии и механизмами
переработки случайных данных. Его архитектура включает несколько
ключевых компонентов:
Для повышения устойчивости к атакам используется несколько пулов энтропии. Каждый пул представляет собой хэш-аккумулятор (обычно на основе SHA-256), в который поступают события из различных источников:
Каждый пул индексируется и используется поочерёдно, чтобы предотвратить предсказуемость накопления энтропии.
Особенности:
Это снижает риск компрометации всей системы при утечке состояния одного пула.
Каждое добавление случайных данных сопровождается оценкой количества энтропии в битах. Это значение передаётся вместе с данными:
sjcl.random.addEntropy(data, estimatedEntropy, source);
Где:
data — входные данныеestimatedEntropy — оценка случайностиsource — строка-идентификатор источникаPRNG ведёт внутренний счётчик накопленной энтропии и не разрешает генерацию криптографически стойких чисел, пока не достигнут минимальный порог (обычно 128 бит).
Основу генератора составляет потоковый шифр, реализованный через блочный шифр AES в режиме счётчика (CTR). Внутреннее состояние PRNG включает:
Генерация случайных данных происходит путём шифрования возрастающего счётчика:
output = AES_encrypt(counter, key);
counter++;
Ключевые свойства:
Reseed — это процесс обновления внутреннего состояния генератора на основе накопленной энтропии. Он выполняется:
Во время reseed:
Формально:
new_key = SHA256(old_key || entropy_data)
Это обеспечивает:
PRNG в SJCL имеет несколько состояний готовности:
Метод проверки:
sjcl.random.isReady();
Возвращает уровень готовности:
0 — не готов1 — частично готов2 — полностью готовВ браузерной среде SJCL автоматически подключает следующие источники:
Date.now() и performance.now()При наличии поддерживаемого API используется:
crypto.getRandomValues()
Это предпочтительный источник, так как он предоставляет криптографически стойкие случайные данные от операционной системы.
Допускается ручное добавление энтропии:
sjcl.random.addEntropy([1,2,3,4], 2, "manual");
Рекомендуется использовать:
Важно корректно оценивать энтропию, так как завышение оценки может привести к ослаблению безопасности.
Основной метод:
sjcl.random.randomWords(n, paranoia);
Где:
n — количество 32-битных словparanoia — уровень требуемой энтропииПример:
var random = sjcl.random.randomWords(4, 6);
Уровень paranoia влияет на:
Архитектура PRNG в SJCL учитывает несколько классов атак:
1. Предсказание состояния
2. Компрометация состояния
3. Недостаток энтропии
4. Replay-атаки
Ключевые поля объекта PRNG:
_pools — массив хэш-пулов_poolEntropy — оценка энтропии по пулам_reseedCount — количество reseed_key — текущий ключ_counter — счётчик_strength — текущий уровень энтропииcrypto.randomBytes)При попытке генерации без достаточной энтропии:
Это предотвращает использование слабых случайных данных в криптографических операциях.
PRNG допускает:
Это делает SJCL гибким инструментом для различных сценариев, включая браузерные приложения с повышенными требованиями к безопасности.