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

Многие незащищенные генераторы случайности (или энтропии) будут делать что-то похожее на следующее:
function getRandom(timestamp, maxNumber){
// Take the deterministic hash of the timestamp
const hashedTime = sha256(timestamp)
// Reduce the hash to within the range [0, maxNumber)
return hashedTime % maxNumber
}
Эта функция (игнорируя некоторые детали реализации модульной математики таким большим числом) будет возвращать случайные числа, основанные на входной метке времени, которая называется seed. Если я передам много разных временных меток, различные выходные данные будут выглядеть случайными. Это пример слабого генератора псевдослучайных чисел.
Слабый генератор псевдослучайных чисел отлично работает, если вы пытаетесь:
- Создание образца данных для приложения
- Написать движок видеоигры
- и т.д …
Слабая псевдослучайность может быть катастрофически опасной, если кто-то пытается:
- Генерация биткойн-ключей
- Создание паролей или солей
- и т.д …
Сильная псевдослучайность (криптографически безопасная)
Программная система, такая как Qvault, в лучшем случае может генерировать надежные псевдослучайные данные, потому что мы работаем над детерминированными системами. Без внешнего источника энтропии (вроде того, что кто-то бросает кости и сообщает компьютеру каждый результат), мы находимся во власти псевдослучайности.

В Node встроено crypto.randomBytes — криптографически безопасный генератор случайных чисел, основанный на openssl. В зависимости от операционной системы пользователя randomBytes будет использовать
/dev/urandom(unix)
or
CryptoGenRandom (Windows)
Хотя это все еще псевдослучайные источники, важно то, что они не могут быть угаданы злоумышленником. Другими словами, после использования crypto.randomBytes() для создания кода восстановления в Qvault злоумышленник не может воссоздать этот код.
Что я делаю?
Короче говоря, используйте crypto.randomBytes() всякий раз, когда вам нужны необработанные случайные байты. Если вам нужно случайное число в диапазоне, например, случайное число от 0 до 9, используйте непредвзятую функцию, которая использует crypto.randomBytes() в качестве источника энтропии. Например:
Удачи и всегда проверяйте источник!
Первоначально опубликовано на https://qvault.io.