JWTセキュリティ完全ガイド:デコード、検証、よくある脆弱性対策
ユーティリティ(更新: 2026年5月1日)
JWTとは?
JWT(JSON Web Token)は、当事者間で情報を安全にやり取りするためのオープン標準(RFC 7519)です。OAuth 2.0やOpenID Connectで広く使われる、現在最も普及しているAPI認証方式の一つです。
JWTの構造
JWTは . で区切られた3つの部分で構成されます。
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
│ Header │.│ Payload │.│ Signature │
| 部分 | 内容 | エンコード |
|---|---|---|
| Header | アルゴリズム + タイプ | Base64URL |
| Payload | クレーム(claims) | Base64URL |
| Signature | 署名 | アルゴリズム(Header + Payload, Secret) |
⚠️ HeaderとPayloadはBase64URLエンコードであり、暗号化ではありません。誰でもデコードして内容を読めます。
ToolsKuでJWTをデコード
手順
- JWTデコードツール を開く
- JWT文字列を貼り付け
- デコードされたHeaderとPayload JSONを確認
- 有効期限、発行者などのフィールドをチェック
よく使うPayloadフィールド
| フィールド | 意味 | 例 |
|---|---|---|
sub |
主体(ユーザーID) | "user_12345" |
iss |
発行者 | "https://auth.example.com" |
aud |
対象者 | "api.example.com" |
exp |
有効期限(Unix秒) | 1717200000 |
iat |
発行時刻 | 1717196400 |
nbf |
有効開始時刻 | 1717196400 |
jti |
JWT ID(一意識別子) | "a1b2c3d4" |
JWT署名アルゴリズム
| アルゴリズム | 種類 | 安全性 | 用途 |
|---|---|---|---|
| HS256 | 対称 | 中 | 単一サービス、内部API |
| HS384/HS512 | 対称 | 中〜高 | 高いセキュリティ要件 |
| RS256 | 非対称 | 高 | マルチサービス、OAuth |
| ES256 | 非対称 | 高 | モバイル、IoT |
| none | 署名なし | ❌ 危険 | 絶対に使わない |
対称 vs 非対称
HS256(対称):
署名: HMAC-SHA256(header.payload, shared_secret)
検証: 同じ shared_secret
問題: 全サービスが同一秘密鍵を共有 — 漏洩の影響が広い
RS256(非対称):
署名: RSA-SHA256(header.payload, private_key)
検証: RSA-SHA256(header.payload, public_key)
利点: 公開鍵は配布可能、秘密鍵は発行者のみが保持
よくあるセキュリティ脆弱性
1. alg: none 攻撃
攻撃者がHeaderの alg を none に変更し、Signature部分を削除します。
// 元のHeader
{"alg": "HS256", "typ": "JWT"}
// 攻撃による改ざん
{"alg": "none", "typ": "JWT"}
防御:サーバー側で許可アルゴリズムをホワイトリスト化し、none を拒否する。
2. 鍵混乱攻撃
RS256をHS256に変更し、公開鍵をHMAC秘密鍵として使う:
攻撃者が公開鍵を取得 → algをHS256に変更 → 公開鍵で署名 → サーバーが公開鍵でHMAC検証 → 通過
防御:Headerの alg が期待値と一致することを厳密に検証する。
3. 機密情報の漏洩
PayloadはBase64エンコードのみのため、JWTに絶対に保存してはいけないもの:
- ❌ パスワード、クレジットカード番号
- ❌ 個人のプライバシー情報
- ✅ ユーザーID、ロール、権限
4. 不適切な有効期限
// ❌ 有効期限なし — トークンが永久に有効
{"sub": "user_123"}
// ❌ 有効期限が長すぎ — 漏洩後も長期間有効
{"sub": "user_123", "exp": 1893456000} // 2030年
// ✅ 適切な期限 + リフレッシュ機構
{"sub": "user_123", "exp": 1717200000} // 15〜60分
JWTベストプラクティス
1. 短期Access Token + Refresh Token
Access Token: 15〜60分で失効、API呼び出しに使用
Refresh Token: 7〜30日で失効、新しいAccess Token取得に使用
2. 保存場所
| 保存方式 | XSSリスク | CSRFリスク | 推奨 |
|---|---|---|---|
| localStorage | 高 | 低 | ❌ |
| sessionStorage | 高 | 低 | ❌ |
| HttpOnly Cookie | 低 | 高 | ⚠️ CSRF対策が必要 |
| メモリ変数 | 低 | 低 | ✅ SPA向け |
3. 検証チェックリスト
サーバーでJWTを検証する際は必ず確認:
- 署名が有効か
-
expが期限切れでないか -
nbfが有効開始済みか -
issが期待する発行者か -
audに現在のサービスが含まれるか -
algがホワイトリスト内か
JWT問題のデバッグ手順
- JWTをデコード:JWTデコードツール でHeaderとPayloadを確認
- expを確認:トークンは期限切れか?
- algを確認:署名アルゴリズムは期待通りか?
- iss/audを確認:発行者と対象者は正しいか?
- 署名を検証:JWTジェネレーター で同じ秘密鍵で再署名して比較
- 伝送を確認:Authorizationヘッダーは
Bearer <token>形式か?
関連ツール
- JWTデコード — HeaderとPayloadを解析
- JWTジェネレーター — テスト用にJWTを生成
- HMAC計算 — HMAC署名の仕組みを理解
- Base64エンコード/デコード — JWTで使うエンコード方式
まとめ
JWTは現代API認証の基盤ですが、Base64エンコード(暗号化ではない)という特性が独特のセキュリティ課題を生みます。構造、署名、よくある脆弱性を理解することはフルスタック開発者に必須です。ToolsKuのJWTデコードツールは認証問題の切り分けに便利ですが、デコードは検証ではありません。本番環境では必ずサーバー側で署名を検証してください。
#JWT#认证#安全#OAuth#API