トークンをフィールドに貼り付けると、3つのボックスがリアルタイムに更新されます(入力は約300 msデバウンスされます)。
100%ブラウザ内: 本ツールは純粋なHTML+JavaScriptです。あなたのJWT、Secret、公開鍵はすべてあなたの端末で処理され、サーバーには一切送信されません。
ヒント: 本番の検証はブラウザではなくサーバーのAuthレイヤーで行ってください。本ツールはデバッグ、リバースエンジニアリング、学習用です。
JWTとは?
JSON Web Token(JWT、発音は "jot")はRFC 7519で定義されたコンパクトな署名済みJSONオブジェクトです。Claimsを2者間で運びます。典型的にはAuthサーバーとAPIの間です。サーバーは認証成功後にトークンを発行し、クライアントは各API呼び出しで`Authorization: Bearer ...`ヘッダーで添付します。
JWTはドットで結ばれた3つのbase64urlエンコード部から成ります。暗号化されていません。署名のみです。トークンを手にした者は誰でも内容を読めるため、パスワードや他の機密はpayloadに入れてはいけません。
サーバーサイドセッションに対する利点: JWTはself-containedです。APIサーバーはAuthサーバーに連絡したりセッションストアを問い合わせたりせずにトークンを検証してパーミッションを取り出せます。水平スケールに優れる代わりに、個別トークンの早期失効が困難になります。
Header、Payload、Signatureの解説
各JWTは単一のドットで結ばれた3つのパートから成ります:
- Header: 小さなJSONオブジェクト。`alg`(アルゴリズム、例 HS256、RS256、ES256)と`typ`(通常 "JWT")を含みます。場合により`kid`(key ID)で署名鍵のヒントを付けます。
- Payload: Claimsを保持するJSONオブジェクト。標準フィールドは`iss`(issuer)、`sub`(subject)、`aud`(audience)、`exp`(expiration)、`nbf`(not before)、`iat`(issued at)、`jti`(unique token ID)。カスタムフィールドも許可されます。
- Signature: `base64url(header) + "." + base64url(payload)`に対し設定したアルゴリズムで計算します。完全性を保護し、鍵を知らなければ内容を気付かれずに変更できません。
重要: base64urlはエンコーディングであり、暗号化ではありません。HeaderとPayloadはどの観察者にも読めます。
JWT 対 セッションCookie
両者とも認証状態を保持しますが、やり方が異なります:
- セッションCookie: 不透明なID。サーバーはセッションストアで完全な状態を引き当てます。即時失効可能ですが、リクエストごとに参照が必要です。
- JWT: 状態自体を運び、署名のみで保護されます。参照不要、マイクロサービスに最適。代わりに早期失効はallow/denyリストが必要です。
- サイズ: JWTは通常300から1500バイト。セッションIDは約32バイト。多数のAPI呼び出しでJWTサイズが帯域に積み上がります。
- Storage: ブラウザではCookie(HttpOnly、Secure、SameSite)が安全な保存先です。localStorageはXSSに晒されます。
目安: 純サーバーアプリにはセッション、APIゲートウェイとモバイルバックエンドにはJWT。理想は短い寿命とリフレッシュトークンフローです。
JWTセキュリティ: `algorithm: none`への対応
近年JWTライブラリには大きなバグがいくつかありました。最大の落とし穴:
- `alg: none`: ヘッダーがそう主張すると未署名トークンを受け入れたライブラリがありました。修正: `none`を絶対許可せず、許可アルゴリズムをサーバー側で固定します。
- HS256/RS256混同: 攻撃者がRSA公開鍵をHMAC Secretとして使ってトークンを署名し、サーバーがRS256ではなくHS256として検証して騙されます。防御: 許可`alg`をサーバーで固定。
- `kid`インジェクション: `kid`フィールドは鍵を指しますが、サニタイズしないとパストラバーサルやSQLインジェクションになり得ます。値を信頼できない入力として扱ってください。
- 弱いSecret: 鍵に "secret" や "password" を使ったHS256トークンは数秒でブルートフォース可能です。最低256ランダムビット、できれば`crypto.getRandomValues()`または`/dev/urandom`から取ってください。
- 長い寿命: 発行されたJWTは満了まで有効で、ユーザーがログアウトしても変わりません。短寿命(15分)+ リフレッシュトークン、機微なエンドポイントには deny リストを使ってください。
OWASPチートシートとRFC 8725(JWT Best Current Practices)は必読です。
JWTの検証手順
完全な検証は署名だけではありません。サーバーコードでの順序:
- ヘッダーをパースし、`alg`をホワイトリストに照合(例 RS256のみ許可)。
- Issuer設定に対応する鍵で署名を検証。JWKSではlookupに`kid`を使うが、値を先にホワイトリスト化します。
- 標準Claimsを検証: `iss`が想定発行者と一致、`aud`が自身のAudienceを含む、`exp`が未来、`nbf`と`iat`が過去(時計のずれを少し許容)。
- カスタムClaims(ロール、テナントID、Scopes)をビジネスモデルに対して検証。
- 早期失効が必要なら、deny / logoutリストをチェック。
確立されたライブラリ(jose、jjwt、jsonwebtokenなど)に頼り、自作コードに頼らないでください。暗号は趣味プロジェクトではありません。
AuthバックエンドをKernelHostでホスト
JWT Issuerとリソースサーバーには信頼できる低遅延のバックエンドが必要です。KernelHostはFrankfurt FRA01で自社のVPSとDedicatedサーバーを運用し、DDoS対策、IPv4 + IPv6、1 Gbit/sアップリンクを備えます。欧州エンドユーザーへの低RTT、フェアな価格、ベンダーロックインなし。本社はWien(AT)、データセンターはFrankfurt(DE)です。