CSPRNG (Cryptographically Secure Pseudo-Random Number Generator) в криптографических библиотеках вроде TweetNaCl.js играет ключевую роль: от качества случайности зависит стойкость ключей, одноразовых чисел (nonce), соли и всех криптографических примитивов.
В основе любого CSPRNG лежит не математическая «случайность» в классическом смысле, а физическая энтропия операционной системы. Современные ОС собирают шум из множества источников:
Эти данные поступают в системный пул энтропии, где проходят смешивание (whitening), чтобы устранить статистические зависимости.
Далее формируется состояние генератора, из которого уже выводятся криптографически стойкие последовательности.
TweetNaCl.js не реализует собственный генератор случайных чисел — он опирается на платформенные CSPRNG.
Основной механизм:
crypto.getRandomValues()Он работает поверх Web Crypto API и обращается напрямую к CSPRNG операционной системы. Внутри браузера это обычно:
Важно: этот интерфейс синхронный и предназначен специально для криптографии.
Используется:
require('crypto').randomBytes()Внутри Node.js это также обёртка над системным CSPRNG (OpenSSL + системные вызовы ОС).
В библиотеке NaCl (и её JavaScript-реализации TweetNaCl.js) случайные значения требуются в нескольких местах:
Типичный вызов:
const nacl = require('tweetnacl');
const keyPair = nacl.box.keyPair();
Внутри keyPair() вызывается генерация 32 байт случайных
данных через:
nacl.randomBytes(n)А уже эта функция делегирует вызов платформенному CSPRNG.
В JavaScript существует встроенный генератор:
Math.random()
Он:
CSPRNG отличается принципиально:
Большинство современных CSPRNG строятся по схеме DRBG (Deterministic Random Bit Generator), описанной в NIST SP 800-90A.
Обобщённая модель выглядит так:
state₀ = seed(entropy)
stateₙ₊₁ = f(stateₙ, counter, key)
outputₙ = g(stateₙ)
Функции f и g построены на
криптографических примитивах:
Важно различать:
CSPRNG гарантирует:
Один из ключевых элементов CSPRNG — периодическое обновление состояния.
Если злоумышленник получает доступ к состоянию генератора в момент времени T, без reseed он может:
Поэтому современные CSPRNG:
В криптографических протоколах NaCl особую роль играют nonce.
Например:
const nonce = nacl.randomBytes(24);
Здесь важно:
CSPRNG обеспечивает:
Типичная ошибка — попытка создать псевдослучайный генератор вручную:
let seed = Date.now();
function badRandom() {
seed = (seed * 9301 + 49297) % 233280;
return seed / 233280;
}
Проблема:
CSPRNG решает это фундаментально: внутреннее состояние не раскрывается через выход.
TweetNaCl.js построен на принципе:
Поэтому генерация случайности делегируется:
Это снижает риск:
На уровне системы:
Важный момент: JS-код не имеет доступа к внутреннему состоянию генератора.
CSPRNG считается безопасным, если выполняются условия:
TweetNaCl.js полагается на эти свойства как на базовую предпосылку всей криптосистемы.
В контексте криптографической системы:
Любая деградация CSPRNG автоматически приводит к компрометации: