Подписывающий и верификатор JWT

Подпишите токен своим ключом, проверьте его по секрету, PEM, JWK или живому JWKS — и постройте набор ключей, который публикует ваш API. Вся криптография выполняется в вашем браузере.

JWT заслуживает доверия ровно настолько, насколько его подпись. Прочитать токен может любой — декодирование ничего не доказывает, — поэтому этот инструмент делает то, чего не может декодер: он подписывает токены вашим ключом (HS256/384/512, RS256/384/512, ES256/384/512, EdDSA), проверяет их по секрету, открытому ключу PEM или JWK, вставленному JWKS или живому URL JWKS с сопоставлением kid, и строит JWKS, который публикует ваш собственный API. Сопутствующее руководство подписание и проверка JWT объясняет, почему декодирование — это не проверка, как работает атака с подменой алгоритма и что «проверено» доказывает, а что — нет. Чтобы прочитать токен без ключа, используйте декодер JWT; для самих ключей набор ключей SSH покрывает генерацию и преобразование.

Последнее обновление:

Подписать токен

🔒 Подписание и проверка выполняются локально с помощью WebCrypto. Секреты и закрытые ключи никогда не отправляются, не сохраняются и не записываются в журнал — обновите страницу, и они исчезнут.

Ваши ключи никогда не покидают эту страницу

Подписание и проверка используют WebCrypto вашего браузера, на ключах, которые вы вставляете или генерируете здесь. Секреты и закрытые ключи живут только в памяти страницы: они не загружаются, не записываются в localStorage или cookies и никогда не попадают в URL. Обновите или закройте страницу — и они исчезнут. Единственное исключение — получение JWKS по URL, которое вы запускаете сами: оно отправляет только введённый вами URL, чтобы получить открытые ключи, — и никогда секрет. Прочитайте подписание и проверка JWT, прежде чем вставлять производственный ключ куда-либо.

Честные ограничения

Для EdDSA нужен современный браузер: WebCrypto Ed25519 нет в старых браузерах, и эта страница говорит об этом прямо, вместо того чтобы подделывать подпись. ECDSA P-256 предлагается как запасной вариант, работающий везде.

Зашифрованный PEM (закрытый ключ, заблокированный парольной фразой) в версии 1 не поддерживается. Страница отказывается от него открыто — сначала расшифруйте его командой openssl pkcs8 -topk8 -nocrypt и никогда не вставляйте парольную фразу на веб-страницу.

Получение JWKS по URL зависит от того, отправляет ли этот сервер заголовки CORS. Многие поставщики удостоверений отправляют; когда один не отправляет, получение честно завершается неудачей, и страница предлагает вставить JWKS вместо этого. Получаются только открытые ключи — URL JWKS никогда не несёт секрета.

Когда подписание важнее декодирования

Декодировать JWT — значит прочитать его: заголовок и полезная нагрузка — это base64url, и любой, у кого есть токен, может увидеть и то и другое. Вот почему один декодер никогда не может ответить на единственный вопрос, который имеет значение, — действительно ли эмитент подписал это? Подписание — вторая половина работы: тот, у кого есть закрытый ключ (или секрет HMAC), создаёт подпись, а проверка повторяет ту же математику с открытым ключом. Эта страница держит обе половины в вашем браузере, потому что ключи здесь — самые чувствительные входные данные, с которыми вообще имеет дело веб-инструмент.

Это разделение важнее всего для асимметричных алгоритмов. С HS256 секрет, который проверяет, — тот же секрет, который подписывает: любой, кто может проверить ваши токены, может их и выпускать, что нормально внутри одного сервиса и утечка — везде в остальном. С RS256, ES256 или EdDSA ключ подписания остаётся у эмитента, а путешествует только открытый ключ: ваш API может публиковать свой JWKS, ротировать ключи, добавляя новый kid, и позволять каждому проверяющему в мире проверять токены, никогда не держа в руках возможность подделать один.

Что инструмент отказывается делать

Два отказа — намеренные. Первый — alg: none: токен, заявляющий, что подпись ему не нужна, отклоняется сразу, с показанной причиной, — проверяющий, который его принимает, принимает подделки. Второй — подмена алгоритма: токен RS256, предложенный с секретом HMAC (или наоборот), завершается неудачей с явным предупреждением и никогда не переосмысливает ключ молча в другом семействе. Оба — классические атаки на JWT, и оба защищены структурно: семейство ключа должно совпадать с семейством alg токена, иначе проверка завершается неудачей.

Третий отказ тоньше: эта страница никогда не скажет вам, что токену «доверяют». Действительная подпись доказывает, что токен был подписан ключом, а проверка срока — что он находится внутри своего окна, — и ничего больше. Доверять ли этому ключу — решение о том, откуда он взялся: JWKS, полученный по известному URL вашего поставщика удостоверений, открытый ключ, который вы закрепили сами, секрет, который вы сгенерировали. Руководство подписание и проверка JWT проходит по тому, что «проверено» доказывает, а что — нет.

Термины JWT — точно

JWT. JSON Web Token (RFC 7519): компактный, безопасный для URL способ передавать утверждения между сторонами — заголовок.полезная нагрузка.подпись, каждый в кодировке base64url. Полезная нагрузка читается любым; только подпись зависит от секрета.

JWS. JSON Web Signature (RFC 7515): формат подписания, лежащий в основе JWT. JWT — это JWS, чья полезная нагрузка — набор утверждений в формате JSON.

JWK. JSON Web Key (RFC 7517): объект JSON, представляющий один криптографический ключ — kty и материал ключа (n/e для RSA, x/y для EC, x для Ed25519, k для общего секрета).

JWKS. JSON Web Key Set: объект с массивом «keys» — стандартный способ, которым эмитент публикует свои открытые ключи, обычно по адресу /.well-known/jwks.json.

kid. Key ID: утверждение заголовка, говорящее, какой ключ подписал токен. Проверяющий сопоставляет его с JWKS; без него используется набор с одним ключом, и страница так и говорит.

alg. Утверждение заголовка, называющее алгоритм подписания (HS256, RS256, ES256, EdDSA…). Проверяющий должен закреплять принимаемые им алгоритмы — доверять собственному утверждению alg токена и есть атака с подменой.

HMAC. Hash-based Message Authentication Code: симметричная подпись — один и тот же секрет подписывает и проверяет. Быстро и просто; каждый держатель секрета может выпускать токены.

RSASSA-PKCS1-v1_5. Схема подписи RSA, лежащая в основе RS256/384/512: хэш оборачивается и возводится в закрытую степень. Детерминированна — тот же вход всегда даёт те же байты подписи.

EdDSA. Edwards-curve Digital Signature Algorithm: здесь Ed25519 — маленькие ключи, быстрая проверка, детерминированные подписи. Для поддержки WebCrypto нужен современный браузер.

Часто задаваемые вопросы

Безопасно ли вставлять закрытый ключ на эту страницу?

На этой странице ключ никогда не покидает ваш браузер: подписание выполняется в памяти страницы с помощью WebCrypto, ничего не загружается, не сохраняется и не записывается в журнал, а обновление стирает его. Небезопасный шаблон — подписание на стороне сервера, где ваш закрытый ключ пересекает сеть. Даже локально используйте устройство, которому доверяете, — и считайте вставленный производственный ключ раскрытым, если машина общая. Вместо вставки настоящих ключей генерируйте здесь тестовые.

Почему мой токен RS256 не проверяется моим секретом?

Потому что секрет и ключ RSA — разные семейства, и страница отказывается их смешивать — этот отказ и есть защита от подмены алгоритма. Токену RS256 нужен открытый ключ RSA эмитента (PEM, JWK или JWKS); секрет может проверять только HS256/384/512. Если у вас есть открытый ключ не в той форме, преобразуйте его: вкладка JWKS преобразует PEM ⇄ JWK.

Что на самом деле отправляет получение JWKS по URL?

Один GET-запрос на введённый вами URL с запросом JSON. Никакой ключ, секрет, токен или идентификатор с ним не уходит — ответом будет набор открытых ключей. Если сервер не отправляет заголовки CORS, браузер блокирует чтение, и страница предлагает вставить JWKS вместо этого.

Мой токен проверяется здесь, но API его отклоняет. Почему?

Проверка здесь сверяет подпись и временное окно с ключом, который вы предоставили. API проверяет ещё и утверждения: эмитента (iss), которого он ожидает, аудиторию (aud), которую он обслуживает, и является ли идентификатор ключа (kid) тем, которому он сейчас доверяет. Токен, подписанный ключом, выведенным из ротации, или выпущенный для другой аудитории, проверяется математически и всё равно отклоняется — правильно.

EdDSA не работает в моём браузере. Что теперь?

Ed25519 нужен современный браузер — в старых его поддержки в WebCrypto вообще нет, и эта страница говорит об этом, вместо того чтобы подделывать. Используйте ES256 (ECDSA P-256) как запасной вариант: он поддерживается везде, где есть WebCrypto, и страница может сгенерировать ключ за вас. Если Ed25519 необходим, обновите браузер.