logo
GeekFormat

JWT デコーダー

Encoded Token172 chars2026-07 更新
header
payload
signature
Valid JWTHS256
Secret38 chars
Header
{
  "alg": "HS256",
  "typ": "JWT"
}
Payload
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1516239022
}
Claims details4 items
sub· サブジェクト1234567890
name· NameJohn Doe
admin· Admintrue
iat· 発行日時15162390222018/01/18 09:30:22
Header details2 items
algHS256HMAC(対称)
typ· TypeJWT
All operations run locally in your browser; the Token and key are never sent to any server.

JWT(JSON Web Token)をデコードしてHeader・Payload・署名を検証。OAuth認証のデバッグ、APIトークンのトラブルシューティングに最適。

関連おすすめ

ユースケース

  • JWT のオンラインデコード:OAuth 2.0 / OIDC のログインデバッグ中に、Header のアルゴリズムや Payload の Claims をすばやく確認します
  • JWT 署名検証:Secret または公開鍵で署名を検証し、401 の原因が署名不一致、期限切れ、アルゴリズム違いのどれかを切り分けます
  • 連携テスト用 JWT 生成:バックエンドに一時実装を頼まず、ブラウザ上でテスト用鍵ペアから JWT を発行できます
  • PEM ↔ JWK 変換:OIDC IdP から渡された JWK をサーバーが PEM で必要とする場合、OpenSSL スクリプトを書かずに形式を確認できます
  • 401 Unauthorized の調査:期限、alg と Gateway 側設定、鍵の一致、PEM の整形を順番に確認できます
  • RS256 と PS256 の比較:同じ RSA 鍵ペアでアルゴリズムを切り替え、OIDC Provider や AWS SigV4 との違いを確認できます
  • JWT の内部構造を学ぶ:alg を変える、Payload を編集する、キーを差し替える、といった操作で署名が壊れる様子をその場で確認できます

特徴

  • デコード・検証・生成を1画面で完結:Token を貼り付けると Header/Payload/Signature に分解し、アルゴリズムとキーを切り替えて署名検証し、Claims を編集して再署名までできます
  • 13種類のアルゴリズムに対応:HS256/HS384/HS512、RS256/RS384/RS512、ES256/ES384/ES512、PS256/PS384/PS512、EdDSA を扱え、OAuth 2.0、OIDC、JWS、API Gateway、SSO の確認に使えます
  • PEM と JWK に対応:RSA、ECDSA、Ed25519 の鍵を PEM 文字列または JWK JSON として読み込めます。OIDC の `/.well-known/jwks.json` の出力もそのまま確認できます
  • HMAC Secret の入力形式を選択:UTF-8 文字列、Hex バイト列、Base64/Base64URL の Secret を切り替えられるため、「見た目は同じなのに署名が合わない」問題を切り分けやすくなります
  • 鍵ペアをブラウザで生成:RSA-2048、RSA-4096、P-256、P-384、Ed25519 のテスト用鍵ペアを生成し、PEM と JWK の両形式で確認できます
  • Claims を意味付きで表示:exp / iat / nbf を人が読める時刻へ変換し、期限切れ・未有効・発行時刻の状態を強調表示します。Header の alg / typ / kid も個別に確認できます
  • 100% クライアントサイド:解析、検証、署名はブラウザ標準の Web Crypto API で実行され、Token、キー、Payload はブラウザの外へ送信されません
  • ワンクリックコピー:Header、Payload、Signature、新しく生成した Token を個別にコピーでき、ドキュメント、チケット、curl コマンドへ貼り付けやすくなっています

使い方

  1. Token を貼り付ける:JWT 文字列を入力欄に入れると、Header、Payload、Signature に自動分解され、それぞれ JSON として整形表示されます
  2. アルゴリズムを選ぶ:HS256 / RS256 / ES256 / PS256 / EdDSA などを切り替えます。Header.alg から推定し、不一致があれば分かるように表示します
  3. キーを読み込む:HMAC Secret、PEM 文字列、JWK JSON を貼り付けます。非対称アルゴリズムでは「鍵ペア生成」からテスト用キーをすぐ作れます
  4. 検証または再署名する:Decode モードでは公開鍵で署名を検証し、Encode モードでは Claims を編集して秘密鍵で署名し、新しい Token を作成します

よくある質問

JWT はどの3つの部分でできていますか?

JWT は `Header.Payload.Signature` という形式です。各セグメントは Base64URL エンコードされています。Header には HS256 や RS256 などのアルゴリズムと typ が入り、Payload には sub、iat、exp、nbf、aud、iss などの Claims が入ります。Signature は最初の2つのセグメントに対する鍵付き署名で、改ざん検知のためのものであり、内容を隠すものではありません。

デコード後に Payload を編集できますか?

表示して編集することはできますが、正しい Token を偽造できるわけではありません。Header や Payload を1文字でも変更すると元の Signature は無効になり、サーバーは拒否します。変更後の Token を有効にするには、同じアルゴリズムとキーで再署名する必要があります。このツールはデコード、編集、生成を同じ画面で扱えるため、テスト用 Token をすばやく作れます。

HS256、RS256、ES256、PS256、EdDSA の違いは?

HS256 は HMAC + SHA-256 で、同じ Secret を署名と検証に使う共通鍵方式です。RS256 は RSA の秘密鍵で署名し公開鍵で検証する方式で、OIDC でよく使われます。PS256 は RSA-PSS を使う RS256 の安全性を高めた選択肢です。ES256 は P-256 楕円曲線を使い、署名が短くなります。EdDSA(Ed25519)は高速で決定的な署名が特徴の新しい方式です。

JWT がいつも 'Invalid Signature' になるのはなぜですか?

よくある原因は、サーバーの Secret または公開鍵と貼り付けたキーが一致していない、PEM の改行や余分な空白が混ざっている、Base64 と Base64URL を取り違えている、Header は HS256 なのに RS256 として検証している、Secret を Hex/Base64 として二重に解釈している、などです。まずキー、アルゴリズム、Secret の入力形式を固定して確認してください。

同じ RSA 鍵で RS256 と PS256 を相互検証できますか?

**できません。** RS256 は RSASSA-PKCS1-v1_5、PS256 は RSA-PSS で、パディングも検証ロジックも違います。同じ RSA 鍵を使っていても、RS256 で署名した Token は PS256 では検証できません。署名側と検証側で必ず同じアルゴリズムを選び、RSA-PSS では saltLength の設定もそろえてください。

alg: none 攻撃とは何ですか?どう防ぎますか?

攻撃者が Header を `{"alg":"none"}` に書き換え、署名なし Token を通そうとする古典的な JWT 脆弱性です。RS256 を HS256 に書き換えて公開鍵を Secret のように使わせる亜種もあります。防御策は明確で、サーバー側で `algorithms: ['RS256']` のように許可アルゴリズムを固定し、Token Header に検証方式を決めさせないことです。

PEM と JWK はどう変換しますか?どちらが一般的ですか?

PEM は `-----BEGIN PUBLIC KEY-----` で囲まれた Base64 文字列で、OpenSSL、Java、Go など従来のサーバー環境でよく使われます。JWK は `kty`、`n`、`e`、`kid`、`alg` などを含む JSON で、OAuth 2.0 / OIDC の標準的な鍵表現です。OIDC IdP は通常 `/.well-known/jwks.json` で公開鍵を JWK として公開します。このツールでは PEM と JWK の両方を読み込めます。

ブラウザだけで JWT 署名を検証できますか?

できます。ブラウザ標準の Web Crypto API(`window.crypto.subtle`)は HMAC、RSA、ECDSA、RSA-PSS、Ed25519 の署名・検証に対応しています。このツールはフロントエンドで `crypto.subtle.importKey` と `crypto.subtle.verify` を使うため、Token やキーをアップロードせずに検証できます。Web Crypto は HTTPS または localhost のような安全なコンテキストで利用できます。

Token はサーバーに送信されますか?

送信されません。解析、検証、署名はすべてブラウザ内の Web Crypto API で実行されます。Token、Header、Payload、Signature、Secret、秘密鍵、生成した鍵ペアはサーバーへ送られません。DevTools の Network タブを開けば、Token 内容を含む外部リクエストがないことを確認できます。

JWT にユーザーの機密情報を入れても安全ですか?

**安全ではありません。** 通常の JWT Payload は平文で、Token を持つ人なら誰でも Base64URL デコードして読めます。パスワード、本人確認番号、クレジットカード番号、API キー、access token、refresh token などは入れないでください。秘匿が必要な場合は JWE や AES など、暗号化を前提にした仕組みを使います。

JWT デコーダーとは?

JWT(JSON Web Token)は、RFC 7519 で定義されたオープン標準です。HTTP リクエスト、OIDC フロー、マイクロサービス間通信で「このユーザーは誰か」「どの権限を持つか」といった主張(Claims)を安全に受け渡すために使われます。標準的な JWT は、Base64URL エンコードされた Header、Payload、Signature の3つのセグメントを `.` でつないだ文字列です。Header にはアルゴリズムと種類、Payload には Claims、Signature には Header.Payload に対する鍵付き署名が入ります。

**JWT は暗号化ではありません**。ここは最も誤解されやすい点です。通常の JWT Payload は平文で、誰でも Base64URL デコードして内容を読めます。JWT が提供するのは「改ざんされていないことの確認」であって、内容の秘匿ではありません。たとえるなら、読めないチケットではなく、偽造防止スタンプ付きのチケットです。検証側は、チケットの内容が読めるかではなく、そのスタンプが本物かを確認します。

JWT では用途に応じて複数の署名アルゴリズムを使い分けます。HMAC 系(HS256/HS384/HS512)は署名と検証に同じ Secret を使うため、単一サービスや信頼された内部クラスタで扱いやすい方式です。RSA 系(RS256/RS384/RS512)は秘密鍵で署名し公開鍵で検証するため、OIDC でよく使われます。RSA-PSS 系(PS256/PS384/PS512)はより新しいパディングを使う方式です。ECDSA 系(ES256/ES384/ES512)は署名が短く、EdDSA(主に Ed25519)は高速かつ決定的な署名が特徴です。

本番で JWT を安全に使うには、いくつかの基本を外せません。パスワード、本人確認番号、カード番号、API キーのような機密情報を Payload に入れないこと。サーバー側で Token Header の `alg` を信用せず、許可するアルゴリズムを固定すること。HMAC Secret は短い文字列ではなく十分にランダムな値にすること。そして署名だけでなく、`exp`、`nbf`、`iss`、`aud` も検証することです。このツールでは Claims の状態を強調表示し、署名の問題なのか、時刻や Claims の問題なのかを切り分けやすくしています。

JWT はセッションの完全な置き換えではありません。セッションは状態をサーバー側の Redis や DB に置き、JWT は状態を Token の中に持たせます。マイクロサービス、ステートレス API、モバイルアプリ、CORS が絡む構成では JWT が便利ですが、即時失効や強制ログアウトが重要な業務システムではセッションの方が扱いやすい場合もあります。このツールは JWT の解析、署名検証、Payload 編集、再署名までをまとめて確認できる作業台です。

Code Examples

50 lines of Node.js: hand-written HS256 sign and verify

javascript

Distills 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'))  // false

Browser-side: Web Crypto API for HMAC signing

html

The 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)

javascript

Use 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

python

The 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'])

Supported Video Formats

FormatMIMEBrowser supportWhen to use
HS256 / HS384 / HS512HMAC + SHA-256/384/512Universal共通鍵方式のアルゴリズムです。同じ Secret で署名と検証を行うためシンプルで高速ですが、Secret は十分にランダムで、少なくとも32バイト以上にしてください。
RS256 / RS384 / RS512RSASSA-PKCS1-v1_5 + SHA-2Web Crypto API最もよく使われる非対称署名です。秘密鍵で署名し、公開鍵で検証します。多くの OIDC IdP、API Gateway、企業 SSO の既定として使われます。
PS256 / PS384 / PS512RSA-PSS + SHA-2Web Crypto APIRS256 より新しい RSA-PSS ベースの方式です。AWS SigV4、AWS Cognito、現代的な OIDC Provider で使われることがあります。saltLength の設定を明示的にそろえる必要があります。
ES256 / ES384 / ES512ECDSA + P-256/P-384/P-521Web Crypto API楕円曲線署名です。署名が短く、JWT 全体を小さくできます。Apple Sign in with Apple では ES256 が標準的に使われます。
EdDSA (Ed25519)Ed25519Modern browsers次世代の高性能署名アルゴリズムです。同じメッセージと同じキーなら同じ署名になり、nonce 再利用のリスクがありません。OAuth 2.1 以降の新しい設計でも推奨される方向です。

Output Example

A real MP3 file encoded to a Data URI — copy-ready:

Header (Base64URL):  eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload(Base64URL):  eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNzE2MjM5MDIyfQ
Signature:           kZJfaYjK3iCkVFL5EL9zGRZ5SmD8_x2h6B5c7pVFfVGo

Header をデコード:
  {
    "alg": "HS256",
    "typ": "JWT"
  }

Payload をデコード:
  {
    "sub": "1234567890",
    "name": "Jane Doe",
    "iat": 1716239022        // 2024-05-20 14:23:42 UTC
  }

Privacy & Security

この JWT ワークベンチは、ブラウザ標準の Web Crypto API を使って100%ブラウザ内で動作します。貼り付けた Token、Header、Payload、Signature、HMAC Secret、RSA/ECDSA の秘密鍵、生成した鍵ペア、署名・検証処理はすべて端末内にとどまり、サーバーへ送信されず、ログ保存も解析もキャッシュもされません。ページ読み込み後はオフラインでも利用できます。ただし、本番の長期有効 Token や本番秘密鍵を無造作にオンラインツールへ貼り付けない、という基本方針は守ってください。

Authoritative References

Troubleshooting

Invalid Signature:'signature is invalid'

Token と検証キーが一致していません。よくある原因は、サーバー側のキーと貼り付けたキーが違う、末尾スペースや改行など見えない文字が混ざっている、Base64 と Base64URL を取り違えている、Header は HS256 なのに RS256 として検証している、といったものです。 まずキーがバイト単位で一致しているか確認してください。PEM の末尾改行、HMAC Secret の余分な空白、JWK の `k` 値が誤って URL デコードされていないかを見ます。次に Header.alg と実際に選んだアルゴリズムが一致しているか、Secret の入力形式が UTF-8 / Hex / Base64 のどれかを固定して確認します。

HTTP 401 Unauthorized:期限切れ、または iat が未来

署名検証は通っているものの、`exp` が過去、`nbf` が未来、または `iat` がサーバー時刻より未来になっています。ローカル環境やコンテナ、CI では時刻ずれが原因になることもあります。 このツールの Claims 表示で exp / nbf / iat の状態を確認してください。exp が赤なら再発行、nbf が赤なら有効開始時刻、iat が未来ならサーバーとクライアントの時刻同期を確認します。

PEM または JWK の読み込みエラー

PEM に余分な空行がある、`-----BEGIN PUBLIC KEY-----` などのヘッダー/フッターが欠けている、JWK に `kty` / `n` / `e` / `kid` など必要なフィールドがない、JWK の `k` 値が Base64URL でない、といった原因が考えられます。 PKIX 形式の標準 PEM を再エクスポートするか、OIDC Discovery の `/.well-known/jwks.json` から取得した JWK をそのまま使ってください。コピー時に改行や引用符、エスケープが崩れていないかも確認します。

RS256 と PS256 の言語間署名エラー

RS256 は RSASSA-PKCS1-v1_5、PS256 は RSA-PSS を使います。同じ RSA 鍵でも相互検証はできません。RS256 で署名した Token は PS256 では失敗し、その逆も同じです。 署名側と検証側で同じアルゴリズムを使ってください。AWS SigV4 は PS256、一般的な OIDC IdP は RS256 を使うことが多いです。RSA-PSS では `saltLength` も重要なので、Node、Go、OpenSSL など実装ごとの設定をそろえます。

alg: none 攻撃と HS256 鍵すり替え攻撃

サーバーが Token Header の alg を見て検証方式を決めている場合、攻撃者が `alg: none` に書き換えて署名なし Token を通そうとしたり、RS256 の Token を HS256 に書き換えて公開鍵を Secret のように使おうとしたりできます。 サーバー側では必ず `algorithms: ['RS256']` のように許可アルゴリズムを固定し、Token 側の alg に検証方式を決めさせないでください。このツールでは Header.alg と実際に選んだアルゴリズムを別々に表示し、不一致を確認できます。