JWT
{
"alg": "HS256",
"typ": "JWT"
}{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"iat": 1516239022
}sub· Субъект1234567890name· NameJohn Doeadmin· Admintrueiat· Время выпуска1516239022→ 18.01.2018, 09:30:22algHS256HMAC (симметричный)typ· TypeJWTБесплатный онлайн-инструмент для JWT: декодирование, валидация и генерация JWT Token. Просмотр Header, Payload и подписи для отладки аутентификации API.
Похожие
Сгенерировать секретный ключ HMAC-SHA256 для подписи JWT HS256
JWT HS256 — это HMAC плюс Base64URL — сначала изучите HMAC, затем JWT
Понять кодировку Base64URL, которую JWT использует внутри
Header, Payload и Signature JWT все закодированы в Base64URL
Декодировать в Base64URL каждый из трех сегментов JWT
После разделения JWT декодируйте в Base64URL сегменты, чтобы прочитать открытый текст
Используйте JWE или AES, когда нужно зашифровать Payload
Payload JWT по умолчанию является открытым текстом; чувствительные payload должны использовать JWE / AES
Понять хеш SHA-256, на котором построен HS256
HS256 — это HMAC плюс SHA-256 — сначала поймите SHA-256
Обратитесь к вашему API напрямую с JWT, который вы только что сгенерировали
После отладки JWT вставьте его в Authorization: Bearer для тестирования API
Тестировщик регулярных выражений
Что такое Декодирование, Проверка и Генерация JWT?
JWT (JSON Web Token) — это открытый стандарт, определенный IETF в RFC 7519 (RFC 7515 описывает форму подписи JWS, RFC 7516 описывает шифрование JWE, RFC 7517 определяет ключи JWK) для безопасной передачи 'заявленной' информации о пользователе между HTTP-запросами, потоками OIDC и вызовами микросервисов. Стандартная строка JWT состоит из трех сегментов, закодированных в Base64URL: Header (алгоритм и тип), Payload (Claims, данные пользователя) и Signature (подпись на основе ключа над первыми двумя). Три сегмента соединены точкой `.`, например `eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0In0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c`.
**JWT — это не шифрование.** Это самое распространенное заблуждение. Payload по умолчанию является открытым текстом — любой может декодировать его в Base64URL и прочитать содержимое. JWT обеспечивает **обнаружение подделки**, а не конфиденциальность: сервер переподписывает Header.Payload общим ключом и сравнивает с Signature токена. Если они совпадают, токен не был изменен при передаче. Это метафора 'железнодорожного билета с антиподдельным штампом': инспектору важно, настоящий ли билет, а не читаем ли QR-код.
JWT четко разделяет ответственность между 13 алгоритмами. **Семейство HMAC** (HS256/HS384/HS512) использует симметричный ключ для подписи и проверки, быстрое и простое, подходит для одного сервиса или доверенного кластера; секретный ключ должен быть как минимум длиной дайджеста (например, ≥ 32 байт для HS256). **Семейство RSA** (RS256/RS384/RS512) использует RSASSA-PKCS1-v1_5, наиболее распространенную асимметричную схему — подписанты имеют приватный ключ, проверяющие имеют публичный ключ. **Семейство RSA-PSS** (PS256/PS384/PS512) использует более новый padding RSA-PSS с более сильными гарантиями безопасности, предпочитается AWS SigV4 и современными провайдерами идентификации OIDC. **Семейство ECDSA** (ES256/ES384/ES512) использует эллиптические кривые (P-256/P-384/P-521 соответственно) с более короткими подписями и лучшей производительностью. **EdDSA** (в основном Ed25519) чрезвычайно быстр и детерминирован (одно и то же сообщение + один и тот же ключ = одна и та же подпись каждый раз) и является рекомендуемым алгоритмом в OAuth 2.1 и новых протоколах.
Безопасность — это то, где JWT спотыкается в production. OWASP JWT Cheat Sheet перечисляет как минимум четыре жестких правила: (1) никогда не помещайте пароли, национальные идентификационные документы, номера карт или API-ключи как открытый текст в Payload; (2) сервер должен **никогда не доверять полю alg**, объявленному в Header Токена — должен проверять с жестко закодированным алгоритмом, иначе атакующий, переписывающий заголовок на `alg: none`, обходит все (это источник исторических CVE, таких как CVE-2015-9235); (3) секретные ключи HMAC должны быть случайными и иметь как минимум 32 байта, никогда короткие строки; (4) проверка — это больше, чем просто проверки подписи — вы также должны валидировать `exp` (истечение срока), `nbf` (not-before), `iss` (эмитент) и `aud` (аудитория). Этот инструмент выделяет каждый из этих Claims в UI, чтобы вы могли сразу увидеть, является ли сбой проблемой подписи, проблемой времени или проблемой Claims.
JWT не заменяет сессии. Сессии хранят состояние пользователя на сервере (Redis или база данных); JWT упаковывает состояние в токен. Архитектуры микросервисов, stateless API, мобильные клиенты и конфигурации с большим количеством CORS выигрывают от JWT; традиционные корпоративные системы и потоки, требующие мгновенного отзыва (например, 'выгнать этого пользователя сейчас'), по-прежнему лучше обслуживаются сессиями. Этот инструмент охватывает как чистую отладку JWT, так и шаги парсинга Токена / проверки подписи / редактирования Payload миграции с сессий на JWT.
Варианты использования
- Онлайн-декодирование JWT: быстрое разделение токена при отладке входа OAuth 2.0 / OIDC для проверки алгоритма Header и Claims Payload
- Проверка подписей JWT: используйте секретный ключ / публичный ключ для проверки подписей токенов в реальном времени и определения, является ли 401 'плохой подписью', 'истекшим' или 'несоответствием алгоритма'
- Генерация тестовых JWT во время интеграции: выпустите JWT в браузере с тестовой парой ключей, без необходимости временно изменять код backend для выдачи токена
- Конвертация PEM ↔ JWK: OIDC IdP дал вам JWK, но серверу нужен PEM (или наоборот) — конвертируйте на месте вместо написания скрипта OpenSSL
- Диагностика 401 Unauthorized: пошагово проверяйте истечение срока, соответствие alg шлюзу, соответствие ключа и форматирование PEM
- Сравнение RS256 и PS256: многие провайдеры OIDC по умолчанию используют RS256, тогда как AWS SigV4 предпочитает PS256 — переключайте алгоритмы с той же парой ключей RSA и сравнивайте результаты
- Изучение внутренностей JWT: измените alg, отредактируйте Payload, переключите ключ в браузере и наблюдайте, как подпись ломается в реальном времени — намного быстрее, чем чтение RFC
Как использовать
- Вставьте или введите токен: поместите строку JWT в поле ввода; инструмент автоматически разделит Header, Payload и Signature и отобразит каждый как отформатированный JSON
- Выберите алгоритм: переключайтесь между HS256 / RS256 / ES256 / PS256 / EdDSA; инструмент выводит из Header.alg и помечает любые несоответствия
- Импортируйте ключ: вставьте секретный ключ HMAC, строку PEM или JSON JWK; для асимметричных алгоритмов нажмите 'Сгенерировать пару ключей', чтобы немедленно получить тестовый ключ
- Проверьте или подпишите заново: в режиме Decode проверяйте публичным ключом и смотрите '✅ подпись действительна / ❌ подпись недействительна'; в режиме Encode редактируйте Claims и подписывайте приватным ключом, чтобы создать новый токен
Output Example
A real MP3 file encoded to a Data URI — copy-ready:
Header (Base64URL): eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 Payload (Base64URL): eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNzE2MjM5MDIyfQ Signature: kZJfaYjK3iCkVFL5EL9zGRZ5SmD8_x2h6B5c7pVFfVGo
Функции
- Декодирование + Проверка + Генерация в одном месте: вставьте токен, чтобы разделить Header/Payload/Signature, переключите алгоритм и ключ для проверки подписи, отредактируйте Claims и подпишите заново, чтобы создать новый токен — покрывает полную цепочку устранения неполадок JWT
- Поддерживаются все 13 алгоритмов: HS256/HS384/HS512 (HMAC), RS256/RS384/RS512 (RSA-PKCS1-v1_5), ES256/ES384/ES512 (ECDSA), PS256/PS384/PS512 (RSA-PSS), EdDSA — покрывает OAuth 2.0, OIDC, JWS, API-шлюзы и корпоративные SSO
- Форматы PEM и JWK: ключи RSA, ECDSA и Ed25519 принимают строки PEM (с заголовками -----BEGIN PUBLIC KEY-----) и JSON JWK (поля kid/kty/n/e) — вставьте напрямую вывод OIDC /.well-known/jwks.json
- Множество форм ввода секретного ключа HMAC: необработанная строка UTF-8, hex-байты или кодированный Base64/Base64URL — переключайте одним кликом, чтобы никогда не случалось 'выглядит так же, но подпись не проходит'
- Автоматическая генерация пар ключей: пары ключей RSA-2048, RSA-4096, P-256, P-384 и Ed25519 генерируются в браузере, представлены в форматах PEM и JWK для немедленного использования в тестах
- Семантическое выделение Claims: exp / iat / nbf автоматически конвертируются в читаемое время с выделенным статусом истек / еще-не-действителен / выдан; alg / typ / kid в Header помечены индивидуально
- 100% на стороне клиента, нулевая загрузка: каждый парсинг, проверка и подпись работают через нативный Web Crypto API браузера — токены, ключи и payload никогда не покидают браузер, следуя принципу безопасности 'никогда не вставляйте production-токены в случайные онлайн-инструменты'
- Копирование одним кликом: Header, Payload, Signature и только что сгенерированный токен копируются независимо для документации, тикетов и команд curl
Примеры кода
50 lines of Node.js: hand-written HS256 sign and verify
javascriptDistills JWT's core mechanism: encode Header and Payload in Base64URL, then HMAC-SHA256 the `header.payload` string. In production, use a library like jsonwebtoken or jose — this snippet exists to make signature failures debuggable.
const crypto = require('node:crypto')
function b64url(input) {
return Buffer.from(input)
.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '')
}
function hmacSign(data, secret) {
return b64url(crypto.createHmac('sha256', secret).update(data).digest())
}
function sign(payload, secret) {
const header = b64url(JSON.stringify({ alg: 'HS256', typ: 'JWT' }))
const body = b64url(JSON.stringify(payload))
const signature = hmacSign(`${header}.${body}`, secret)
return `${header}.${body}.${signature}`
}
function verify(token, secret) {
const [h, p, s] = token.split('.')
const expected = hmacSign(`${h}.${p}`, secret)
const a = Buffer.from(s)
const b = Buffer.from(expected)
return a.length === b.length && crypto.timingSafeEqual(a, b)
}
const SECRET = 'my-super-secret-key'
const payload = { userId: 42, role: 'admin', exp: Math.floor(Date.now() / 1000) + 3600 }
const token = sign(payload, SECRET)
console.log(token)
console.log(verify(token, SECRET)) // true
console.log(verify(token, 'wrong-key')) // falseBrowser-side: Web Crypto API for HMAC signing
htmlThe core idea of this tool's front-end: use the browser's native crypto.subtle for HMAC, RSA, ECDSA, RSA-PSS and Ed25519 verification — no third-party library needed. Drop this into any HTML page to mint HS256 tokens.
<!doctype html>
<html>
<body>
<pre id="out"></pre>
<script>
const out = document.getElementById('out')
const b64url = buf =>
btoa(String.fromCharCode(...new Uint8Array(buf)))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
const b64urlStr = str => b64url(new TextEncoder().encode(str))
async function sign(payload, secret) {
const header = b64urlStr(JSON.stringify({ alg: 'HS256', typ: 'JWT' }))
const body = b64urlStr(JSON.stringify(payload))
const data = new TextEncoder().encode(`${header}.${body}`)
const key = await crypto.subtle.importKey(
'raw',
new TextEncoder().encode(secret),
{ name: 'HMAC', hash: 'SHA-256' },
false,
['sign']
)
const sig = await crypto.subtle.sign('HMAC', key, data)
return `${header}.${body}.${b64url(sig)}`
}
;(async () => {
const token = await sign({ user: 'alice', role: 'admin' }, 'browser-demo-secret')
out.textContent = token
})()
</script>
</body>
</html>Node.js: verify RS256 with jose (the right way)
javascriptUse a mature library like jose, jsonwebtoken, or PyJWT in production — never roll your own. This snippet shows how jose verifies an RS256 token, prints the failure reason on error (alg mismatch, bad signature, expired, kid not found, etc).
import { jwtVerify, importSPKI } from 'jose'
import { readFile } from 'node:fs/promises'
const token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.payload.signature'
const publicKeyPem = await readFile('public.pem', 'utf8')
try {
const { payload, protectedHeader } = await jwtVerify(
token,
await importSPKI(publicKeyPem, 'RS256'),
{
issuer: 'https://idp.example.com',
audience: 'my-app',
algorithms: ['RS256'], // critical: algorithm whitelist blocks alg:none and HS256-substitution attacks
}
)
console.log('alg =', protectedHeader.alg)
console.log('sub =', payload.sub)
} catch (err) {
console.error('verify failed:', err.code, err.message)
// common: ERR_JWT_EXPIRED / ERR_JWS_INVALID / ERR_JWS_SIGNATURE_VERIFICATION_FAILED
}Python: parse a token and print its Claims with PyJWT
pythonThe most common way to debug JWT on the Python side. PyJWT's decode() validates exp / nbf / iat by default and returns the result as a plain dict.
import jwt
token = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0In0.SflKxw'
# Parse (no signature check, just look at Header and Payload)
print(jwt.get_unverified_header(token))
# {'alg': 'HS256', 'typ': 'JWT'}
print(jwt.decode(token, options={'verify_signature': False}))
# {'sub': '1234'}
# Full verification
claims = jwt.decode(
token,
'my-super-secret-key',
algorithms=['HS256'],
audience='my-app',
issuer='my-service',
)
print(claims['sub'])Сравнение 5 типов алгоритмов подписи JWT: какой выбрать?
JWT — это не один алгоритм, а 5 семейств алгоритмов с разными компромиссами по ключам, производительности, безопасности и совместимости. Сначала определите сценарий, а затем выбирайте алгоритм — это поможет избежать многих проблем.
| Алгоритм | Тип | Ключ | Производительность | Типичные сценарии | Предостережения |
|---|---|---|---|---|---|
HS256 | HMAC симметричный | Один и тот же Secret | Очень быстрый | Внутри кластера сервисов, доверенная среда, монолитные приложения | Secret нельзя раскрывать проверяющей стороне; минимум 32 случайных байта |
RS256 | RSA асимметричный | Приватный ключ подписывает / публичный проверяет | Средняя | OIDC, API-шлюзы, корпоративный SSO, когда нужно разделение публичного/приватного ключа | Использует RSASSA-PKCS1-v1_5; между языками нужно зафиксировать padding |
PS256 | RSA-PSS асимметричный | Приватный ключ подписывает / публичный проверяет | Средняя | AWS SigV4, AWS Cognito, новые OIDC IdP | Нужно явно зафиксировать saltLength (OpenSSL/jose=32, Go=длина хеша) |
ES256 | ECDSA асимметричный | Приватный ключ подписывает / публичный проверяет | Быстрый + короткая подпись | Apple Sign in with Apple, мобильные, низкая пропускная способность | Различные кривые (P-256/P-384/P-521) должны совпадать с сервером |
EdDSA | Ed25519/Ed448 | Приватный ключ подписывает / публичный проверяет | Очень быстрый (детерминированная подпись) | OAuth 2.1, новые протоколы, высокочастотная проверка | Web Crypto поддерживает Ed25519; Ed448 пока не на всех платформах |
Best Practices
Никогда не вставляйте Secret / приватный ключ production в любое онлайн-инструмент
Хотя этот инструмент обрабатывает 100% локально в браузере (не загружает токены и ключи), устоявшийся процесс отладки легко приводит к тому, что в дальнейшем по привычке Secret / приватный ключ / Access Token production случайно вставляется в незнакомый онлайн-инструмент или утекает через скриншоты. Долгоживущие токены (Refresh Token, приватный ключ production, API Key) должны обрабатываться в локальной контролируемой среде; этот инструмент предназначен только для отладки краткосрочных Access Token, тестовых пар ключей при интеграции и изучения структуры JWT.
OWASP JSON Web Token Cheat SheetСервер должен иметь белый список алгоритмов, никогда не доверять Header.alg токена
Атака alg: none (CVE-2015-9235 и др.) и атака подмены HS256 (использование публичного ключа как Secret для обмана RSA-сервера) происходят из того, что сервер выбирает логику проверки по алгоритму, заявленному в Header. В production-коде должен быть жёстко зафиксирован белый список algorithms, например `algorithms: ['RS256']`, запрещено позволять токену решать, какой алгоритм использовать. При отладке, если Header.alg не совпадает с ожиданием сервера, в первую очередь подозревайте конфигурацию сервера, а не содержимое токена.
Secret HS256 должен быть случайным числом длиной минимум 32 байта
HS256 использует HMAC-SHA256; длина ключа меньше длины дайджеста (32 байта) значительно снижает стоимость перебора. Не используйте короткие строки вроде 'my-secret', 'password123', не склеивайте из названия сервиса/компании/года. Стандартный способ: `openssl rand -base64 32` или `crypto.randomBytes(32).toString('base64url')`, затем сохраните в переменные окружения / KMS / сервис управления ключами, никогда не пишите в код.
Является ли JWT безопасным местом для чувствительной информации о пользователе?В production JWT должен проверять exp / nbf / iat / iss / aud, а не только подпись
Прохождение проверки подписи доказывает только 'не подделан', но не 'ещё не истёк', 'точно подписан этим IdP', 'точно выдан этому приложению'. В production обязательно нужно проверять exp (истечение), nbf (время начала действия), iat (время выдачи), iss (эмитент), aud (аудиторию) — все соответствующие Claim, ничего не пропуская. OWASP явно указывает эти 4-5 пунктов как обязательные. Проверка только подписи без проверки времени — корень многих утечек токенов (refresh token, который никогда не истекает).
Многоуровневое истечение токенов: Access 15-30 минут, Refresh 7-30 дней
Access Token отвечает за вызовы API: чем короче срок истечения, тем безопаснее (после утечки быстро теряет силу); Refresh Token отвечает за обмен Access Token, может быть длиннее, но должен храниться на сервере и быть отзываемым. Распространённый эмпирический опыт: Access 15-30 минут, Refresh 7-30 дней, в сочетании с Refresh Token Rotation (при каждом использовании Refresh для обмена Access одновременно выдаётся новый Refresh, старый немедленно становится недействительным) — это баланс между обнаружением утечки и удобством пользователя.
Без состояния vs с состоянием: JWT — не замена Session
JWT упаковывает состояние в токен, естественно поддерживает горизонтальное масштабирование микросервисов и CORS между доменами, но стоимость отзыва высока (нужен чёрный список или короткий срок истечения). Session хранит состояние в Redis/БД на сервере, может 'выкинуть пользователя', но требует общего хранилища. **Это не выбор одного из двух**: краткосрочный Access JWT + серверная запись сессии Refresh Token — самое распространённое гибридное решение, сочетающее stateless-масштабирование и мгновенный отзыв. Финансовые/государственные системы, требующие мгновенного отзыва, должны осторожно использовать чистый JWT.
Является ли JWT безопасным местом для чувствительной информации о пользователе?Payload по умолчанию является открытым текстом, не помещайте чувствительные данные в JWT
JWT (JWS) по умолчанию не шифрует Payload; любой, у кого есть токен, может декодировать Base64URL и прочитать содержимое. **Категорически нельзя** помещать в Payload пароли, национальные ID-номера, номера кредитных карт, API-ключи, Access Token, Refresh Token. JWT подходит для нечувствительных Claim (ID пользователя, роль, срок истечения, ID арендатора); чувствительные данные сервер запрашивает через sub. Если нужно зашифровать Payload, используйте JWE (RFC 7516), но он в 2-5 раз медленнее и сложнее в управлении ключами — отдавайте приоритет схеме 'нечувствительный Claim + серверный запрос'.
Что такое JWT?RSA-PSS (PS256/PS384/PS512) при кросс-языковой интеграции сначала зафиксируйте saltLength
RS256 и PS256 не могут перекрёстно проверяться (разный padding), и у PS256 есть ещё одна ловушка: параметр `saltLength`. OpenSSL по умолчанию 32 байта, Node jose по умолчанию 32 байта, Python PyJWT по умолчанию равен длине хеша (SHA-256=32), Go по умолчанию `rsa.PSSSaltLengthEqualsHash`. При кросс-языковой интеграции необходимо сначала зафиксировать одно и то же значение (рекомендуется 32 байта), иначе один и тот же RSA-ключ, подписавший токен PS256, не пройдёт проверку в разных языках.
RS256 и PS256 сбои подписи между языкамиПроцесс отладки: используйте тестовые пары ключей, не трогайте production
При интеграции или локальной разработке всегда сначала создавайте совершенно новую тестовую пару ключей (HS256 — случайный Secret, RS256/ES256/EdDSA — пара ключей, сгенерированная инструментом одним кликом); категорически нельзя повторно использовать приватный ключ production IdP или Secret домена компании. После отладки или завершения локального тестирования немедленно уничтожьте тестовые ключи. Функция 'Сгенерировать пару ключей' этого инструмента создана именно для этого: RSA-2048/4096, P-256/P-384, Ed25519 создаются одним кликом и сразу готовы к использованию, после интеграции их можно просто выбросить.
Генерация тестовых JWT во время интеграцииЧасто задаваемые вопросы
Каковы три части JWT?
Строка JWT имеет форму `Header.Payload.Signature`, каждый сегмент закодирован в Base64URL. Header объявляет алгоритм (например, HS256, RS256) и тип токена (typ: JWT); Payload несет Claims пользователя (заявления), общие поля: sub (ID пользователя), iat (время выдачи), exp (время истечения), nbf (not-before), aud (аудитория), iss (эмитент); Signature является результатом подписания первых двух сегментов ключом, цель — 'обнаружение подделки', а не 'анти-утечка'.
Могу ли я редактировать Payload после декодирования?
Вы можете просматривать и редактировать, но **не подделывать**. Как только вы измените Header или Payload, оригинальная Signature станет недействительной, и сервер отклонит проверку. Чтобы модифицированный токен снова стал действительным, вы должны **переподписать** его тем же алгоритмом и тем же ключом — именно поэтому этот инструмент предлагает 'декодирование + редактирование + генерацию' в одном: декодируйте для просмотра, измените и немедленно сгенерируйте новый токен для тестирования, чтобы вам не нужно было каждый раз просить backend временно изменить код для выдачи.
В чем разница между HS256, RS256, ES256, PS256 и EdDSA?
HS256 использует HMAC с общим секретным ключом (симметричный), быстрый, но управление секретным ключом критично. RS256 использует приватные/публичные ключи RSA (асимметричный), эмитент подписывает приватным, проверяющий использует публичный. ES256 использует ECDSA с эллиптическими кривыми (P-256), более короткая подпись. PS256 использует RSA-PSS, безопаснее RS256. EdDSA (обычно Ed25519) быстрый и детерминированный, рекомендуется для OAuth 2.1.
Почему мой JWT продолжает показывать 'Invalid Signature'?
Обычно это потому, что ключ, формат секретного ключа, алгоритм или кодировка Base64URL не совпадают точно. Дополнительный пробел, неправильная новая строка PEM или путаница между Base64 и Base64URL достаточны. Проверьте байт за байтом и подтвердите, что Header.alg соответствует выбранному алгоритму.
Может ли один и тот же ключ RSA перекрестно проверять RS256 и PS256?
Нет. RS256 использует RSASSA-PKCS1-v1_5, PS256 использует RSA-PSS. Даже с одним и тем же ключом RSA они не могут перекрестно проверять. Подписант и проверяющий должны использовать один и тот же алгоритм.
Что такое атака alg:none?
Атакующий меняет Header на `{"alg":"none"}` (без подписи) или заменяет RS256 на HS256 (используя публичный ключ, как если бы он был секретным ключом HMAC). Сервер должен навязать белый список алгоритмов и никогда не позволять токену решать, какой алгоритм использовать.
Как я конвертирую между PEM и JWK?
PEM — это классическая нотация OpenSSL с строками BEGIN/END. JWK — это JSON и он распространен в OAuth/OIDC. OIDC-провайдеры часто публикуют публичные ключи через `/.well-known/jwks.json`. Этот инструмент может напрямую обрабатывать форматы PEM и JWK.
Может ли браузер напрямую проверять подписи JWT?
Да. Нативный Web Crypto API браузера (`window.crypto.subtle`) поддерживает подпись и проверку HMAC, RSA, ECDSA, RSA-PSS и Ed25519, без сторонних библиотек. Этот инструмент использует `crypto.subtle.importKey` и `crypto.subtle.verify` на фронтенде для каждой проверки, поэтому никогда не отправляет ваши токены или ключи. Примечание: Web Crypto доступен только в безопасных контекстах: **HTTPS** или `localhost`.
Мой токен отправляется на сервер?
Нет. Весь парсинг, проверка и подпись в этом инструменте работают в браузере через нативный Web Crypto API. Токен, Header, Payload, Signature, секретный ключ / приватный ключ и любые сгенерированные пары ключей никогда не отправляются на сервер. Откройте вкладку Network DevTools браузера, и вы не увидите исходящего запроса, несущего содержимое токена. Страница может использоваться офлайн после загрузки.
Является ли JWT безопасным местом для чувствительной информации о пользователе?
**Нет.** Payload JWT по умолчанию является открытым текстом — любой с токеном может декодировать его в Base64URL и прочитать содержимое. Шифрования нет. **Никогда не помещайте** пароли, национальные ID-номера, номера кредитных карт, API-ключи, access-токены или refresh-токены в открытом виде в JWT. Если вам нужно шифрование, используйте JWE (RFC 7516) вместо JWS. JWT подходят для нечувствительных Claims (ID пользователя, роль, время истечения, ID арендатора); чувствительные данные должны запрашиваться на стороне сервера с использованием `sub`.
Устранение неполадок
Invalid Signature: 'signature is invalid'
Токен и ключ проверки не совпадают. Обычные причины: (1) ключ сервера и ключ, который вы вставили в инструмент, различаются (самое частое); (2) ключ содержит невидимые символы (пробел в конце, новая строка, символ нулевой ширины); (3) Base64 и Base64URL перепутаны; (4) выбран неправильный алгоритм (Header говорит HS256, сервер проверяет как RS256 или наоборот). Сначала проверьте, совпадает ли ключ байт за байтом: обратите внимание на конечные новые строки PEM, конечные пробелы секретного ключа HMAC и значения `k` JWK, которые могли быть неправильно декодированы URL. Подтвердите, что алгоритм в инструменте соответствует Header.alg токена. Используйте decode-plus-verify этого инструмента, чтобы воспроизвести точную ошибку и подтвердить, что она происходит между 'декодирование успешно' и 'проверка не удалась'.
HTTP 401 Unauthorized: Token Expired или iat в будущем
Проверка подписи прошла, но `exp` находится в прошлом (Token Expired), `nbf` все еще в будущем (Not Before) или `iat` позже текущего времени сервера (часто из-за рассинхронизации часов). Другой распространенный случай — несовпадающий `aud` (аудитория): токен был выпущен для Приложения A, но проверен Приложением B. Используйте выделенную область Claims в этом инструменте, чтобы сразу увидеть статус exp / nbf / iat. Красный exp = истек, перевыпустите. Красный nbf = еще не действителен, проверьте, является ли iat будущим временем. Красный aud = неправильная аудитория, проверьте, правильно ли настроена аудитория на сервере.
Ошибка импорта PEM или JWK
PEM имеет дополнительные пустые строки или отсутствуют маркеры заголовка/подвала (`-----BEGIN PUBLIC KEY-----`); JWK отсутствуют обязательные поля (`kty` / `n` / `e` / `kid`); значение `k` JWK отсутствует padding Base64URL (должен быть заполнен `=` или строго без `=`); приватный ключ RSA импортируется как публичный ключ; приватный ключ Ed25519 (32-байтовое зерно) предоставляется как 64 байта. Переэкспортируйте стандартный PEM PKIX с помощью `openssl rsa -in key.pem -pubout -outform PEM` или `openssl ec -in key.pem -pubout`; для JWK используйте необработанный вывод из эндпоинта OIDC Discovery `/.well-known/jwks.json` вместо ручного кодирования. Этот инструмент автоматически обнаруживает заголовки PEM, отсутствующий padding и отсутствующие поля JWK и дает подсказку.
RS256 и PS256 сбои подписи между языками
RS256 использует RSASSA-PKCS1-v1_5, PS256 использует RSA-PSS. Эти два **не могут перекрестно проверять** — токен, подписанный RS256 с данным ключом RSA, всегда не пройдет проверку PS256, и подпись может отличаться по длине на несколько байт. Убедитесь, что подписант и проверяющий используют один и тот же алгоритм. AWS SigV4 использует PS256, большинство OIDC IdP используют RS256. RSA-PSS также имеет параметр `saltLength` — OpenSSL по умолчанию 32, jose по умолчанию 32, `rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}` Go является правильным эквивалентом. Зафиксируйте это перед тестированием интеграции между языками.
Атака alg: none и атака подмены ключа HS256
Сервер выбирает алгоритм проверки на основе alg, объявленного в Header токена. Атакующий переписывает заголовок на `alg: none` (без подписи) или переписывает токен RS256 на HS256 (используя публичный ключ, как если бы он был общим секретным ключом HMAC) и обходит проверку. Исторические CVE, такие как CVE-2015-9235 (jsonwebtoken) и CVE-2022-23529 (множество Node-библиотек), восходят к этому шаблону. Сервер должен навязать белый список алгоритмов — например `algorithms: ['RS256']` — и никогда не позволять токену решать, какой алгоритм использовать. UI этого инструмента показывает как Header.alg, так и алгоритм, который вы действительно выбрали, и помечает несоответствия: это сама демонстрация в реальном времени 'клиент не должен доверять Header.alg'.
Privacy & Security
Эта рабочая среда JWT работает на 100% в вашем браузере, поддерживается нативным Web Crypto API браузера. Токен, который вы вставляете, Header, Payload, Signature, секретный ключ HMAC, любые приватные ключи RSA/ECDSA, любые сгенерированные пары ключей и каждый расчет подписи/проверки остаются на вашем устройстве — они никогда не отправляются на сервер, никогда не логируются, никогда не анализируются и никогда не кэшируются. Страница может использоваться офлайн после загрузки. Лучшая практика: никогда не вставляйте долгоживущие production-токены или production-приватные ключи в какой-либо онлайн-инструмент, включая этот. Этот инструмент подходит для отладки, тестирования интеграции, обучения и генерации тестовых токенов — production-секретные ключи и приватные ключи должны обрабатываться в контролируемой локальной среде.
Supported Video Formats
| Format | MIME | Browser support | When to use |
|---|---|---|---|
| HS256 / HS384 / HS512 | HMAC + SHA-256/384/512 | Universal | Алгоритм с симметричным ключом: один и тот же Secret используется и для подписи, и для проверки. Он простой и быстрый, хорошо подходит для кластера сервисов внутри доверенной зоны. Secret должен быть не короче 32 байт для HS256, 48 для HS384 и 64 для HS512. |
| RS256 / RS384 / RS512 | RSASSA-PKCS1-v1_5 + SHA-2 | Web Crypto API | Самый распространенный асимметричный алгоритм. Подпись создается закрытым ключом, а проверяется открытым. Это типичный выбор для OIDC-провайдеров, API gateway и корпоративного SSO. |
| PS256 / PS384 / PS512 | RSA-PSS + SHA-2 | Web Crypto API | RSA-PSS — более современная и безопасная замена RS256. AWS SigV4, AWS Cognito и современные OIDC-провайдеры часто выбирают именно его. saltLength нужно задавать явно, иначе проверка может не совпасть. |
| ES256 / ES384 / ES512 | ECDSA + P-256/P-384/P-521 | Web Crypto API | Подписи на эллиптических кривых. Они короче (ES256 занимает всего 64 байта), работают быстро и уменьшают размер JWT. Sign in with Apple по умолчанию использует ES256. |
| EdDSA (Ed25519) | Ed25519 / Ed448 | Web Crypto API | Современный высокопроизводительный алгоритм подписи. Подписи детерминированы (одно сообщение + один ключ = одна и та же подпись), нет риска повторного nonce, поэтому он хорошо подходит для новых протоколов. |
Authoritative References
- Безопасное сравнение строк
- Двоичное Кодирование
- Шифр Цезаря
- Азбука Морзе
- Hex Кодирование
- Видео в Base64
- Base64 в видео
- Изображение в Base64
- Base64 в изображение
- Текст в Base64
- Base64 в текст
- Проверка хеша файла
- Файл в Base64
- Base64 в Файл
- Аудио в Base64
- Base64 в Аудио
- AES-шифрование и расшифровка
- DES Шифрование
- Кодировщик и Декодер Base32
- Base58 кодирование и декодирование
- Кодирование Base64
- Декодирование Base64
- Сравнение Base64
- Разбиение Base64
- Base64 — объединение строк
- Форматирование Base64
- Валидация Base64
- Пакетное кодирование Base64
- Пакетное декодирование Base64
- Очистка Base64
- Обработка заполнения Base64
- Base64 в Hex
- Преобразователь Base64 DataURL
- Base64-Hex конвертер
- Base85 Кодирование
- Генератор и верификатор HMAC
- PBKDF2
- Хеш MD5
- SHA-256 хэш
- SHA1 хеш
- Хеш SHA512
- JWT
- HTML Кодирование
- Unicode экранирование
- URL-кодирование
- Base64 URL-Safe
- MIME Base64
- Обфускация Java
- Обфускация JS
- Обфускация PHP
- Обфускация Python
- Статистика длины Base64