Инструменты разработчика · Генератор UUID
Math.random против crypto.getRandomValues: как работает каждый генератор
· Как это работает
uuid криптография API-интерфейс браузера
Оба возвращают числа, которые выглядят случайными, но одно представляет собой небольшой детерминированный конечный автомат, а другое поступает от операционной системы. Вот что каждый из них делает под капотом и почему UUID должен использовать второй.
Фрагмент форума, в котором создается UUID из Math.random — почему он выглядит хорошо и проходит все случайные тесты
Ответ на форуме предлагает быструю фабрику UUID в восемь строк: переберите значения из Math.random и отформатируйте их в макет 8-4-4-4-12. Код выглядит нормально и проходит все случайные тесты. Каждый идентификатор выглядит по-разному, и короткий образец не показывает очевидной визуальной закономерности. Это не то свойство, которое необходимо для идентификатора, чувствительного к безопасности. JavaScript определяет Math.random как псевдослучайный источник, но не требует криптографической устойчивости к прогнозированию. Подходящие для него задания включают моделирование, игры и перетасовку. Как только идентификатор может повлиять на доступ, обнаружение объекта или другое состязательное решение, внешний вид больше не является доказательством. Документированный контракт генератора имеет большее значение, чем страница правдоподобного результата.
Внутри Math.random — псевдослучайный алгоритм с фиксированным внутренним состоянием, предназначенный для скорости и статистического распространения, а не секретности.
Поскольку Math.random не указан как криптографический генератор, его выходные данные не следует рассматривать как свидетельство того, что будущие значения скрыты от наблюдателя. crypto.getRandomValues имеет другой контракт платформы: он заполняет целочисленный массив криптостойкими значениями. Спецификация Web Crypto оставляет выбор точного генератора пользовательскому агенту, поэтому код приложения не должен заявлять о конкретном алгоритме, размере начального числа или энтропийном устройстве. ToolAcre нужна только поддерживаемая граница: браузер предоставляет безопасные случайные байты, JavaScript получает заполненный массив Uint8Array, а код UUID устанавливает поля версии и варианта. Это утверждение одновременно полезно и переносимо в браузерах, внутренняя реализация которых различается.
Почему наблюдение за выходными данными может выявить состояние — как небольшое состояние означает, что ряд значений может позволить кому-то предсказать следующие.
Код приложения получает криптостойкие значения от getRandomValues, а не реализует или раскрывает состояние JavaScript PRNG. Разница в безопасности проявляется в реальных системах. Идентификатор, созданный на основе Math.random, непригоден там, где прогнозирование может иметь последствия, поскольку злоумышленник, имеющий возможность читать сеть (или любую систему, где видны предыдущие UUID), может предсказать следующий. UUID v4 из crypto.getRandomValues сам по себе не является токеном аутентификации (вам все равно нужен срок действия, хеширование, ограничение скорости), но генератор предназначен для предотвращения прогнозирования. ToolAcre отказывается генерировать идентификатор, если его безопасный источник отсутствует, вместо того, чтобы молча перейти к предсказуемой формуле. Math.random поставляется с небольшими ошибками распространения в основных движках. Выходная последовательность может выглядеть разнообразной, не обеспечивая при этом состязательной непредсказуемости, необходимой для ролей, несущих секрет.
Внутри crypto.getRandomValues — браузер запрашивает CSPRNG операционной системы, который смешивает аппаратную и системную энтропию и спроектирован так, чтобы быть непредсказуемым.
Алгоритмы, специфичные для движка, и их статистическое поведение могут измениться; ни визуальный осмотр, ни случайный тест распространения не превращают Math.random в криптографический источник. Расчеты столкновений также предполагают независимые результаты из указанного пространства. Если генератор повторяет состояние, неправильно инициализируется или заменяется детерминированным приспособлением, это предположение не удалось, и формула больше не описывает реализацию. Оба API могут создавать строки, которые выглядят одинаково нерегулярно. Модель угроз разделяет их: значения, которые должны противостоять прогнозированию, используют crypto.getRandomValues, тогда как симуляции и неконкурентные перетасовки могут использовать Math.random. Выбор следует из последствий предсказания, а не из пунктуации или кажущегося разнообразия выборки.
Рабочий пример — генерация одинакового количества идентификаторов каждым методом и сравнение того, что может сделать наблюдатель.
Генератор ToolAcre UUID использует исключительно crypto.getRandomValues; он никогда не использует Math.random, потому что стоимость предсказуемого UUID всегда выше, чем стоимость немного более медленного генератора. Криптографическую разницу можно измерить с помощью модели угроз. Злоумышленник, желающий подделать UUID, должен либо угадать идентификатор напрямую, либо сломать генератор случайных чисел. Прямое предположение – это не то сравнение, которое дает количественная оценка в этой статье; Подтвержденный вывод заключается в том, что Web Crypto предназначен для криптографической случайности, а Math.random — нет. CSPRNG и Math.random предоставляют разные контракты: первый предназначен для обеспечения случайности, чувствительной к безопасности, а второй не несет в себе таких перспектив. Система, использующая Math.random для идентификаторов, потеряла криптографическое свойство; безопасность теперь зависит от сохранения в секрете последовательности сгенерированных UUID. Если хотя бы один UUID утечет, все будущее поколение окажется под угрозой.
Исторические ошибки распространения — напоминание о том, что движки поставляли реализации Math.random с явно неравномерным выводом, описанным качественно.
Если приложение хранит UUID в журнале, базе данных или истории контроля версий, утечка практически неизбежна. Библиотека ToolAcre принудительно использует crypto.getRandomValues и отказывается генерировать UUID, если безопасный контекст (HTTPS или localhost) недоступен. Это проектное решение предотвращает автоматический возврат к Math.random, который мешал многим реализациям, выполняемым вручную. В Node.js библиотека использует криптомодуль; в браузерах он использует Web Crypto API. Оба поддерживаемых пути запрашивают у платформы криптографически стойкую случайность. Реализация не претендует на производительность, поскольку время определяется механизмом, устройством и рабочей нагрузкой; Контракт безопасности является решающим свойством для идентификаторов. Почему отраслевой стандарт остановился на crypto.getRandomValues, это короткая история неправильного использования UUID. Ранние системы использовали системное время, сетевые интерфейсы и аппаратные часы для генерации идентификаторов.
Чего это не касается — статистическое качество любого генератора для моделирования, что отличается от вопроса непредсказуемости.
Версии UUID на основе времени, узла и случайные решения решают различные проблемы распределения; не следует представлять его как линейный ремонт каждой более ранней конструкции. Для версии 4, RFC 9562 определяются случайные поля и отдельно обсуждается невозможность угадывания. Таким образом, переход от Math.random меняет качество вновь генерируемых значений без изменения текстовой формы UUID. Существующие идентификаторы остаются ключами базы данных; их восстановление приведет к поломке ссылок. Новые значения могут использовать Web Crypto немедленно, в то время как авторизация должна продолжать рассматривать каждый старый или новый UUID как идентификатор, а не доказательство разрешения. Задокументируйте отключение, чтобы лица, реагирующие на инциденты, знали, какой генератор создал каждую популяцию.
Вывод: выбирайте генератор по угрозе, а не по внешнему виду — генератор ToolAcre UUID использует исключительно CSPRNG, никогда Math.random()
При проверке следует различать устаревшие (не подходящие для обеспечения секретности) и новые (поддерживаемые CSPRNG) идентификаторы. В документации должен быть отмечен переход. Генератор ToolAcre создает только crypto.getRandomValues UUID; он не пытается проверять или восстанавливать идентификаторы из других источников. Генератор ToolAcre демонстрирует передовую практику, отказываясь переходить на более слабый случайный источник. Если crypto.getRandomValues недоступен, инструмент сообщает об ошибке вместо того, чтобы автоматически использовать Math.random. Этот принцип проектирования применим к любой критически важной для безопасности системе: лучше громко потерпеть неудачу, чем тихо добиться успеха со слабой гарантией безопасности. Разработчик, который видит сообщение «Ошибка генерации UUID: криптографический код API недоступен», должен устранить основную проблему (обновить до HTTPS, исправить безопасный контекст или предоставить правильный резервный вариант). Разработчик, который молча получает UUID, созданный из Math.random, не имеет никаких признаков того, что система скомпрометирована. Библиотека ToolAcre ставит честность выше удобства.