В основе криптографической стойкости Stanford JavaScript Crypto
Library лежит модуль sjcl.random, реализующий накопление
энтропии и генерацию псевдослучайных значений, пригодных для
криптографических операций.
Генератор не опирается на один источник случайности. Вместо этого используется пул энтропии, который наполняется событиями окружения:
window.crypto (если доступно)Каждое событие преобразуется в числовые данные и добавляется в внутренний буфер энтропии.
Ключевой принцип — накопление достаточного количества неопределённости перед генерацией криптографически стойких значений.
SJCL оперирует не байтами напрямую, а 32-битными словами
(word).
Слово (word) — это беззнаковое 32-битное целое число.
Один элемент массива слов:
[0x12345678, 0x9abcdef0]
Такой формат используется во всех внутренних криптографических операциях: шифрование, хеширование, генерация ключей.
Преобразование:
При необходимости байтового представления используется преобразование:
sjcl.codec.hexsjcl.codec.base64sjcl.codec.utf8StringФункция генерации:
sjcl.random.randomWords(n, paranoia)
n — количество 32-битных словparanoia — уровень требуемой энтропииvar words = sjcl.random.randomWords(4);
Результат:
В SJCL используется концепция уровней требуемой энтропии:
| Уровень | Описание |
|---|---|
| 0 | минимальная защита |
| 1 | базовая криптография |
| 2 | средний уровень |
| 3 | высокий уровень |
| 4 | максимальная защита |
Чем выше уровень, тем больше энтропии требуется перед генерацией результата.
Пример:
var strong = sjcl.random.randomWords(8, 3);
Если энтропии недостаточно, выполнение блокируется.
При недостатке энтропии функция может:
Для асинхронного ожидания используется callback:
sjcl.random.randomWords(4, 3, function (words) {
console.log(words);
});
Такой подход предотвращает использование слабых случайных данных.
Хотя базовая единица — слово, часто требуется байтовый поток.
var words = sjcl.random.randomWords(2);
var hex = sjcl.codec.hex.fromBits(words);
Каждые 2 слова:
Случайные слова используются для:
Пример генерации ключа:
var key = sjcl.random.randomWords(8, 2);
var aesKey = new sjcl.cipher.aes(key);
Размер ключа:
Модуль sjcl.random поддерживает подключение источников
вручную.
Добавление энтропии:
sjcl.random.addEntropy(data, estimatedEntropy, source);
data — числовой массив или числоestimatedEntropy — оценка в битахsource — строковый идентификаторПример:
sjcl.random.addEntropy([mouseX, mouseY], 2, "mouse");
SJCL может автоматически подключать:
addEventListener для mousemoveperformance.now()Пример включения сборщика:
sjcl.random.startCollectors();
После этого библиотека начинает автоматически наполнять пул энтропии.
Перед генерацией можно проверить уровень энтропии:
if (sjcl.random.isReady()) {
var words = sjcl.random.randomWords(4);
}
Также доступна более детальная проверка:
sjcl.random.getProgress(3);
Результат:
В некоторых сценариях требуется сброс пула:
sjcl.random.reset();
После сброса:
Соль часто используется для хеширования паролей:
var salt = sjcl.random.randomWords(4, 3);
var saltHex = sjcl.codec.hex.fromBits(salt);
Размер:
Nonce должен быть уникальным и непредсказуемым:
var nonce = sjcl.random.randomWords(3, 2);
Использование:
Основные проблемы генерации:
Решение:
window.crypto как дополнительного
источникаВ браузере SJCL автоматически получает энтропию из событий DOM.
В Node.js окружении требуется ручное добавление:
sjcl.random.addEntropy(require('crypto').randomBytes(16), 8, "node");
Без этого генератор может оставаться в состоянии “не готов”.
Пул энтропии:
Внутренний алгоритм обеспечивает:
Случайные слова используются не изолированно, а как базовый строительный блок:
Таким образом, качество sjcl.random напрямую определяет
стойкость всей криптосистемы.