ブログ一覧へ
tutorial 2026-06-14

トークンを決して送信しないプライバシーセーフ JWT デバッガー(2026)

トークンを決して送信しないプライバシーセーフ JWT デバッガー

API リクエストが 401 を返し、JWT トークンを取得します —— おそらく期限切れ、おそらく間違ったクレーム、おそらくサーバーが間違った秘密鍵で署名。「これを解析してくれ」と Google で JWT デコーダーを検索し、jwt.io にランディングします。あなたの本番ベアラートークン(5 分間、ユーザーセッションへのフルアクセスを許可する)を彼らのフォームに貼り付けようとしているのに気づき、停止します。

機微性:JWT は単なる JSON ではありません。多くは API キー、署名秘密、ユーザー識別子、または彼らをホールドする人によって偽装または記録できるその他の機密情報を含みます。それらを Web ツールに貼り付けることは、運用上、CC するときに友人に「これは私のパスワードです」を電子メールするのと同等です。

このガイドは JWT が技術的にどう機能するか、署名検証がなぜ重要か、そしてトークンを当社のサーバーを含めどこにも送信せずに JWT トークンをデコードと検証する方法をカバーします。すべての作業をオフラインで実行するために Ai2Done JWT Decoder を使用 —— ブラウザサイド、ネットワーク呼び出しなし。

TL;DR

  • JWT は 3 つの base64url 部分header.payload.signature、ドットで結合。
  • デコーディングは秘密を必要としない(誰でも任意の JWT を読める) —— 検証は公開鍵 (RS256) または共有秘密 (HS256) を必要とする。
  • 本番トークンを Web ツールに貼り付けない——トークン値は典型的には API レスポンスログに収集すべきでない機密です。
  • 信頼ゾーンを離れない完全オフラインデバッグには Ai2Done JWT Decoder を使用。
  • 常に署名検証チェックを使用 —— 「クレームを表示」だけでは攻撃者がペイロードを変更しなかったことを証明しない。

なぜ見た目より難しいのか

JWT は JSON Web Token で、認証クレームのコンパクトな URL セーフ表現の標準です。形は実際にシンプルです:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNTE2MjM5MDIyfQ.
xJ09n0_uvbXdQzZ8mZbS5KkF0Wx9rB1mC7eYUSlxQrI

3 つの base64url エンコードされた部分があります:

  1. ヘッダー — 使用するアルゴリズムを宣言:{"alg": "HS256", "typ": "JWT"}
  2. ペイロード — 実際のクレーム:{"sub": "user-123", "name": "Alice", "iat": 1640000000, "exp": 1640003600}
  3. 署名 — 暗号化検証:base64url(HMACSHA256(base64url(header) + "." + base64url(payload), secret))

トリッキーな部分は 誰でもデコードできるが検証は秘密を必要とすることです。攻撃者は本番 JWT をキャッチし、ペイロード部分を変更(例:"role": "user""role": "admin" に変更)し、新しい署名を計算しようと試みます。彼らがサーバーの秘密鍵を持たない限り、サーバーは検証で拒否します。

しかし「読むときは秘密を必要としない」属性は、JWT がデバッグまたは検査されると、彼らがサーバーアクセスログに記録されるか、JIRA に貼り付けられるか、または jwt.io に貼り付けられても、誰でもクレーム値を読めることを意味します。

これがプライバシー機微性が来る場所です:JWT のペイロードはしばしばユーザーの内部 ID、電子メール、組織、役割、または操作される人物に対する個人特定可能情報を含みます。本番ベアラートークンを公開 Web ツールに貼り付けることは、それを彼らのサーバーログに保存し、悪意のあるスクリプトを実行する第三者広告に公開し、CDN レイヤーキャッシュに保存します。

方法 1:Ai2Done JWT Decoder(ブラウザサイド、ネットワーク呼び出しなし)

Ai2Done JWT Decoder はブラウザで純粋に実行 —— ツール JS がロードされた後、トークンはサーバーに触れません。フロー:

  1. 任意のブラウザで /tools/jwt_decoder を開く。
  2. ツールバーで Wi-Fi をオフ(オプションのプライバシー確認、ツールはまだ機能) —— または DevTools の Network タブをチェック:ロード後リクエストなし。
  3. JWT を貼り付け —— インラインに 3 つのパネルに分かれる:ヘッダー、ペイロード、署名。
  4. オプションで検証:右側のテキストエリアに公開鍵(RS256 / ES256 / EdDSA 用 PEM フォーマット)または秘密(HS256 用 raw string)を提供 —— 緑のチェック (✓) または赤の X が現れる。
  5. クレームを検査 —— 既知のクレーム名(iatexpnbfissaud)が翻訳され、UTC タイムスタンプとローカルタイムスタンプ。

すべては Web Crypto API でローカルに行われます:

  • HS256:crypto.subtle.importKey で秘密をインポート、crypto.subtle.verify で署名を検証。
  • RS256 / ES256:crypto.subtle.importKey で公開鍵をインポート、crypto.subtle.verify で署名を検証。
  • EdDSA (Ed25519):libsodium の WASM ビルドを介して、これは標準 Web Crypto にまだない。

何もアップロードされません。ツール JS がブラウザにロードされた後、それは完全に自己完結。

方法 2:CLI 用 jwt-cli

完全に CLI で作業しているなら、jwt-cli を使用:

# インストール
brew install mike-engel/jwt-cli/jwt-cli
# またはどこでも npm
npm install -g jwt-cli

# デコード(秘密なし)
jwt decode eyJ...

# 検証
jwt decode --secret "your-shared-secret" eyJ...

# 公開鍵で RS256 を検証
jwt decode --pub-key-from-file public.pem eyJ...

jwt-cli はネットワークを介して何も送信せず、デバッグループ用に高速、CI スクリプトで自動化できる完全にオフラインです。

方法 3:jq + base64(脱依存)

任意のソフトウェアをインストールできないなら、base64 と jq で JWT をデコードできます:

TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNTE2MjM5MDIyfQ.xJ09n0_uvbXdQzZ8mZbS5KkF0Wx9rB1mC7eYUSlxQrI"

# ヘッダーをデコード
echo "$TOKEN" | cut -d. -f1 | base64 --decode | jq

# ペイロードをデコード
echo "$TOKEN" | cut -d. -f2 | base64 --decode | jq

これは検証なしでクレームを表示します(ペイロードが変更されたかわからない)—— 信頼できないトークンではこれを行わない!しかし「あなたのフリート全体に標準コマンドラインユーティリティしかないとき、ペイロード値を素早く見て」用に動作します。

方法 4:jose.js / pyjwt(プログラム的検証)

サービスの一部としてのプログラム的検証用、信頼できるライブラリを使用:

Node.js

import * as jose from 'jose';

const secret = new TextEncoder().encode('your-secret');
const { payload } = await jose.jwtVerify(token, secret, {
  issuer: 'https://your-issuer.com',
  audience: 'your-audience',
});
console.log(payload);

Python

import jwt

decoded = jwt.decode(
    token,
    public_key,
    algorithms=['RS256'],
    issuer='https://your-issuer.com',
    audience='your-audience',
)

常にアルゴリズムを明示 (algorithms=['RS256'])。共有された秘密で署名された JWT を alg: none に降格して受け入れるアルゴリズム混乱攻撃 —— または HS256 を期待するエンドポイントに RS256 公開鍵で署名された JWT を渡す —— は実世界の脆弱性です。

一般的な落とし穴

「alg: none」攻撃:誰でも {"alg": "none"} ヘッダー、彼らが好きなペイロード、空の署名で JWT を構築できます。検証ライブラリが alg: none を受け入れるなら、攻撃者はサーバーを欺いて任意のクレームを受け入れさせます。常に予期されるアルゴリズムを明示、検証コードでヘッダーに依存しないでください。

アルゴリズム混乱:あなたのコードは RS256(公開鍵で検証)で署名された JWT を期待しますが、攻撃者は HS256 で署名されたものを送信、公開鍵をシークレットとして使用。ライブラリが盲目的にヘッダーの alg を信頼するなら、それは検証として通過します(公開鍵を共有秘密として使用)。期待されるアルゴリズムを明示的に渡す

期限切れトークン:JWT は exp クレーム(Unix epoch 秒)を含むことができます。検証ライブラリはデフォルトでチェックしますが、{ ignoreExpiration: true } を渡したり、exp が含まれていない場合、期限切れトークンは無期限に有効に見えます。常にすべての JWT に exp が必要です;通常は短命(5 分〜1 時間)が安全。

kid(Key ID)ヘッダー攻撃:一部の検証ライブラリは kid ヘッダーを信頼して使用する鍵を選択します。攻撃者は kid を SQL ペイロードまたはパストラバーサル文字列に設定して、データベースクエリまたはファイルシステム読み取りを傷つける可能性があります。許容される kid 値をホワイトリストし、ユーザー制御パスとして決して扱わないでください。

長期トークン:JWT は失効するのが難しいです(彼らは状態を含まない、サーバーは「このトークンは現在無効」と言うために中央レコードと比較する必要がある)。失効可能性のためにセッショントークンよりもアクセストークンに JWT を好む;典型的には JWT は短命で、長命リフレッシュトークン(不透明、サーバーサイドルックアップ)でペアにする。

デコーダーをどう構築したか(技術的ディープダイブ)

Ai2Done JWT Decoder は以下に構築されています:

  • ネイティブ TextDecoderatob / btoa で base64url デコーディング(〜100 行の JS、依存関係なし)
  • HMAC、RSA、ECDSA 署名検証のためのネイティブ Web Crypto APIcrypto.subtle.verify
  • EdDSA (Ed25519) 検証のための libsodium-wasm(〜180 KB バンドル、トークンが EdDSA であることが検出されたときのみ遅延ロード)
  • crypto-js または npm 依存関係なし —— 暗号は標準のブラウザ Web Crypto を介してすべて行われ、これは Chrome、Edge、Firefox、Safari 14+ で機能

興味深いデザインの選択:ヘッダー、ペイロード、署名がデフォルトで色分けされる。これは「貼り付けた JWT のどの部分を読んでいるかわかっていますか?」エラー(ヘッダーをペイロードと比較するなど)を防ぎます。3 つのパネルは異なる背景色を持ち、編集する可能性のあるテキスト(ペイロード)はインライン編集可能;ヘッダーと署名は読み取り専用です。

別の選択:HTTP リクエストを発信しない。Web Crypto API はネイティブブラウザ機能で、ネットワーク呼び出しを必要としません。これは DevTools の Network タブで Wi-Fi をオフにして検証できます。

FAQ

Q: jwt.io は安全ですか? A: jwt.io はトークンをサーバーに送信しないと請求し、彼らの JS は監査済みです —— しかし、本番ベアラートークンには、それは依然として「私の機密データが私の物理的に制御するブラウザ内のみで処理されたことを保証できない」原則を破ります。彼らが侵害されたら(CDN リダイレクト、悪意のあるサードパーティ広告、彼らのページ上の侵害された JS)、貼り付けたトークンは攻撃者の手に。これがエクスペンシブな信頼決定 —— ローカルツールを使用または「これはテストアカウントのトークンだ」原則のみ jwt.io に貼り付ける。

Q: 当社の信頼ゾーンを離れずに jwt.io を実行できますか? A: はい —— jwt.io は MIT ライセンスされ、それを https://github.com/auth0/jwt.io から取得し、自分のラップトップでローカルにオフラインで実行できます。これがオプションだとめったに警告されません。

Q: JWT を Slack で同僚と共有することは安全ですか? A: いいえ —— Slack メッセージはアーカイブされ、Slack 従業員によって読み取り可能(公証)、攻撃者は Slack を侵害(Twilio スタイル)。本番 JWT は Slack で共有しないでください —— 最低限のクレームを編集して貼り付け、または同僚にあなたの認証 API を呼び出して彼ら自身のトークンを取得させる。

Q: 検証なしで JWT をデコードできますか? A: はい、しかしそれを デコード であり 検証 ではないことを認識して扱うこと。デコードされたペイロードは攻撃者によって変更されているかもしれません。検証 (crypto.subtle.verify または jwt.decode(token, secret, algorithms=['RS256'])) だけが署名された確実性を与えます。

Q: 公開鍵を取得するか? A: 多くの OAuth プロバイダー(Auth0、Okta、Google、Microsoft)は <issuer>/.well-known/jwks.json で公開鍵を公開。fetch または curl でアクセス、結果から keys[*] を抽出、デコーダーに貼り付け。

Q: ペイロードに iat (issued at) と exp (expires) があります —— なぜそれは「過去 3 時間」と読みますか? A: タイムゾーンの問題。iatexp は Unix epoch 秒(UTC)で。ツールは UTC とローカル時間の両方を表示します。「過去 3 時間」と表示されたら、それはこの瞬間のあなたのローカルタイムゾーン(または時計のズレ)に比較。

今試す

ネットワーク呼び出しなしで JWT をデコードと検証:

JWT Decoder を開く →

貼り付け、デコード、検証。アップロードなし、サインアップなし、トークンはブラウザに留まります。

関連読み物


最終更新 2026-06-14。JWT Decoder はブラウザで 100% 動作 —— トークンはデバイスを離れません。当社のサーバーログには貼り付けまたは検証したものは含まれません。