Серверные среды исполнения JavaScript исторически развивались вокруг
собственных криптографических примитивов, и лишь позднее начали
приближаться к спецификации Web Crypto API. Несмотря на общую идею
унификации, поведение SubtleCrypto и набор доступных
алгоритмов в браузере и на сервере часто различаются не только по
реализации, но и по архитектурным ограничениям платформ.
В браузере Web Crypto API опирается на встроенные системные библиотеки операционной системы или изолированные реализации, контролируемые браузерным движком. На сервере JavaScript работает в окружении, где криптография почти всегда реализована через нативные биндинги.
В случае Node.js основой выступает OpenSSL, что определяет:
Deno использует аналогичный подход, но стремится к более строгому соответствию стандарту Web Crypto API. Bun, в свою очередь, реализует собственный слой поверх системных библиотек, оптимизируя производительность и частично расширяя API.
В Node.js доступ к Web Crypto API предоставляется через модуль
crypto.webcrypto. Его архитектура представляет собой
адаптацию браузерного стандарта поверх OpenSSL.
Ключевые особенности:
crypto.subtle соответствует спецификации
W3CПоддержка алгоритмов в Node.js не полностью совпадает с браузером:
Отдельной особенностью является наличие legacy-алгоритмов, которые существуют в Node.js, но отсутствуют в Web Crypto API браузеров.
Deno стремится к максимальному соответствию спецификации Web Crypto API. Его реализация:
SubtleCryptoОднако даже в Deno присутствуют системные ограничения:
Deno чаще используется как эталон поведения Web Crypto API в серверной среде, но не всегда совпадает с реальными браузерами по деталям реализации.
Bun реализует Web Crypto API с приоритетом на скорость. В отличие от Node.js и Deno, он активно использует собственные оптимизированные реализации и системные вызовы.
Особенности:
Bun ориентирован на прикладные сценарии, где важнее производительность, чем строгая совместимость с браузером.
Генерация ключей является одной из наиболее чувствительных зон несовместимости.
В браузере параметры RSA строго ограничены:
В Node.js допускаются более гибкие параметры, включая нестандартные экспоненты, что может привести к несовместимости при переносе ключей между окружениями.
Различия проявляются в поддержке кривых:
Web Crypto API стандартизирует форматы:
spki для публичных ключейpkcs8 для приватных ключейjwk как JSON-представлениеСерверные реализации могут расширять эти форматы:
cryptoArrayBuffer-ориентированным
структурамНесовместимость чаще всего возникает при переходе между
JWK и бинарными форматами, особенно при использовании
нестандартных параметров кривых.
Во всех современных серверных реализациях используется криптографически стойкий генератор случайных чисел:
crypto.randomBytesНесмотря на единый принцип, различия возникают в:
Особенно критично это при высоконагруженных системах, где Web Crypto API используется для генерации токенов.
Алгоритмы SHA семейства демонстрируют наибольшую совместимость:
Node.js может предоставлять расширенные варианты через OpenSSL, которые не существуют в браузере.
Основные несовместимости возникают не на уровне алгоритмов, а на уровне API:
ArrayBuffer, TypedArrayBuffer как расширениеЭто приводит к ошибкам при переносе кода без адаптации типов.
DOMExceptionError с кодами
OpenSSLWeb Crypto API не поддерживает потоковую обработку, но серверные обёртки могут её эмулировать, что создаёт расхождения в производительности и логике.
Cloudflare Workers, Vercel Edge Runtime и аналогичные среды реализуют Web Crypto API с ограничениями:
Такие среды ближе к браузерной модели, чем к Node.js, что упрощает перенос фронтенд-кода, но ограничивает криптографическую гибкость.
Практическая совместимость между серверными реализациями достигается через унификацию подходов:
crypto legacy
API)JWKArrayBuffer как
основной формат)Отдельное значение имеет тестирование одних и тех же криптографических операций в нескольких средах исполнения, так как даже минимальные различия в реализации OpenSSL или системных библиотек могут приводить к несовпадению результатов шифрования.
Полная унификация Web Crypto API между браузером и сервером остаётся недостижимой из-за фундаментальных различий архитектур:
Это приводит к тому, что совместимость существует на уровне интерфейсов, но не гарантируется на уровне бинарной эквивалентности результатов в каждом edge case.