Инструменты разработчика · Генератор UUID
Почему crypto.randomUUID() не работает на страницах HTTP: объяснение безопасных контекстов
· Как это работает
uuid криптография API-интерфейс браузера
crypto.randomUUID работает на локальном хосте и на HTTPS, а затем исчезает на простом промежуточном хосте HTTP. В этом посте объясняется правило безопасного контекста, лежащее в основе такого поведения, и то, как безопасно генерировать UUID там, где оно применимо.
TypeError при промежуточном этапе, везде нормально — симптом и разница в среде, которая его вызывает.
Разработчик проверяет свою работу на localhost:3000 и генератор UUID работает отлично. Они развертываются на промежуточной странице http://staging. внутренней. пример. com (обычный HTTP в компании LAN), и код выдает ошибку TypeError: crypto.randomUUID не является функцией. Тот же код на https://example. com работает нормально. Несоответствие сбивает с толку, пока они не прочитают документацию MDN: crypto.randomUUID ограничен безопасными контекстами. Безопасный контекст — это HTTPS или localhost; источник Plain-HTTP на LAN не защищен правилом браузера, даже если сеть является частной. Исправление заключается в использовании crypto.getRandomValues с ручными битовыми операциями или в обновлении промежуточного сервера до HTTPS. Правило безопасного контекста было введено для предотвращения утечки конфиденциальных API в незашифрованные соединения.
Что такое безопасный контекст — правило браузера, которое резервирует определенные API для источников HTTPS и для localhost.
Страница поверх обычного HTTP может быть перехвачена сетевым злоумышленником; раскрытие криптографических API на такой странице позволит злоумышленнику генерировать идентификаторы, используя скомпрометированный API. HTTPS шифрует страницу и все сообщения API, чтобы злоумышленник в сети не мог перехватить или изменить код. Localhost считается безопасным по своей сути, поскольку он существует только на локальном компьютере и не может быть перехвачен по сети. Любой другой источник HTTP (адрес LAN, общедоступный домен без HTTPS, обратный прокси-сервер, который пересылает данные на HTTP) не является безопасным по определению. Web Crypto API разделен на две функции: crypto.randomUUID, ограниченную безопасным контекстом, и crypto.getRandomValues, доступную как в безопасном, так и в незащищенном контексте. Оба используют одну и ту же операционную систему CSPRNG.
Какие части Web Crypto являются закрытыми: crypto.randomUUID и crypto.subtle требуют защищенного контекста, а crypto.getRandomValues — нет.
Разница в том, что getRandomValues не скрывает тот факт, что вы используете криптографию; страница, которая его использует, должна явно запрашивать случайные байты. Функция randomUUID — это удобство, которое также обеспечивает безопасный контекст. Если вашему приложению необходимо генерировать UUID на незащищенной странице, вы должны использовать getRandomValues и вручную установить биты версии и варианта. RFC 9562 определяет битовые операции: установите для байта 6 значение (byte6 и 0x0f) | 0x40 для версии 4 и байт 8 в (byte8 и 0x3f) | 0x80 для варианта RFC. Библиотека ToolAcre делает именно это в качестве запасного варианта, когда случайный UUID недоступен. Воспроизведение ошибки: отправьте простую страницу из обычного источника HTTP, который не рассматривается как потенциально заслуживающий доверия. Проверьте, открыт ли случайный UUID, затем сравните getRandomValues, который разрешен ссылкой Web Crypto в небезопасных контекстах.
Создание UUID версии 4 на основе getRandomValues — резервного варианта маскировки и форматирования, который удерживает вас на CSPRNG, когда отсутствует случайный UUID.
Тот же код в файле, обслуживаемом через HTTPS, может предоставлять случайный UUID. Если в рабочей версии сообщается, что «randomUUID не является функцией», сначала проверьте, является ли источник безопасным контекстом, затем проверьте поддержку браузера и не заменил ли криптообъект другим сценарием. Решением может быть HTTPS или реализация getRandomValues, которая явно устанавливает биты UUID. Полифил Math.random не является эквивалентным запасным вариантом: он воспроизводит форму, удаляя при этом контракт криптографического источника. Тесты, которые утверждают только тире и цифры версии, пропустят эту замену, поэтому просмотрите исходный путь, а также результирующую строку.
Рабочий пример — воспроизведение сбоя в источнике http:// и подтверждение исправления.
Но идентификатор теперь предсказуем. Злоумышленник, перехвативший несколько UUID из вашей системы, может предсказать следующий. Если приложение ошибочно воспринимает такой идентификатор как учетные данные на предъявителя, предсказуемость становится ошибкой авторизации, а не косметическим дефектом. Правильная стратегия — обновить сервер до HTTPS (всегда правильный шаг для любой страницы с аутентификацией или конфиденциальными данными) или использовать getRandomValues с явными битовыми операциями (что требует больше кода, но является криптографически надежным). Безопасный контекст обеспечивается браузером; вы не можете обойти это с помощью переменных конфигурации или среды. Генератор ToolAcre развернут поверх HTTPS, поэтому crypto.randomUUID доступен. Когда вы генерируете UUID в инструменте, он использует либо randomUUID (если проверка безопасного контекста проходит), либо getRandomValues с битовыми операциями (если вы используете простой HTTP, хотя это случается редко).
Почему не следует использовать полифил с Math.random — заманчивый ярлык и затраты на безопасность, которые он несет
Ни один из путей не возвращается к Math.random. Если вы создаете свой собственный генератор UUID и ориентируетесь на незащищенные источники, используйте getRandomValues и выполняйте битовые операции самостоятельно. Проверьте как HTTPS, так и localhost, чтобы убедиться, что randomUUID работает, затем проверьте источник http://, чтобы убедиться, что ваш резервный вариант getRandomValues верен. Понимание ограничений безопасного контекста поможет вам разработать стратегии развертывания. Если ваше приложение должно работать на частной LAN без HTTPS (устаревшая инфраструктура, встроенные системы), резервный вариант getRandomValues — это ваш путь вперед. Если у вас есть выбор, обновите его до HTTPS везде; Вместе с Let's Encrypt это бесплатно, а инвестиции окупаются в обеспечении безопасности всего приложения. Разработка на локальном хосте не имеет ограничений, поэтому перед развертыванием в рабочей среде протестируйте генератор UUID на локальном хосте и на промежуточном этапе HTTPS. Производство всегда должно быть HTTPS.
Что это не охватывает — среды выполнения серверов, такие как Node.js и Deno, которые предоставляют API без правила безопасного контекста.
Ограничение не является ошибкой или неудобством; это функция безопасности, которая предотвращает несчастные случаи и заставляет задуматься о шифровании. В более широком смысле API-интерфейсы веб-криптографии защищены безопасным контекстом. crypto.getRandomValues, крипто. тонкий. шифровать, шифровать. тонкий. GenerateKey и все другие конфиденциальные операции требуют HTTPS или localhost. Нет ни исключений, ни переопределения, ни способа отключить проверку. Одна небезопасная страница нарушает гарантии безопасности для ваших пользователей. Даже если вы стараетесь использовать криптографические API только на определенных страницах, ошибка (или зависимость, включающая генератор UUID) может привести к утечке генерации случайных чисел на незашифрованную страницу. Генератор ToolAcre обеспечивает это на уровне кода: если randomUUID недоступен (незащищенный контекст), он использует getRandomValues, который доступен, но предупреждает любого рецензента кода о том, что происходит что-то необычное.
Вывод: исправьте источник, а не генератор — ToolAcre обслуживается через HTTPS, поэтому его генератор по замыслу работает в безопасном контексте.
Еще лучше, он отказывается генерировать идентификатор, если безопасный контекст действительно недоступен (в средах, где getRandomValues также недоступен, что редко, но возможно в старых или встроенных системах). Миграция существующей системы на HTTPS для поддержки API безопасной криптографии — распространенный проект. Начните с источника, где генерируются UUID (ваш сервер аутентификации, серверная часть API или служба приложения ключей). Получите сертификат TLS (Let's Encrypt предоставляет его бесплатно). Настройте свой веб-сервер для обслуживания HTTPS по умолчанию и перенаправления запросов HTTP на HTTPS. Проверьте работу нескольких браузеров и клиентов API, чтобы убедиться, что все работает. Затем проверьте свой код на наличие оставшихся криптографических API, которые могут вызываться на незашифрованных страницах, и исправьте их. Генератор ToolAcre предполагает HTTPS; если вы его используете, вы уже часть пути к цели.