JWT デコーダー
あらゆる JSON Web Token をデコードして、ヘッダー・ペイロード・クレームを読みやすい形で確認し、必要に応じて HMAC(HS256/384/512)署名を検証できます。処理はすべてブラウザ内で完結します。
JWT デコーダー の使い方
- 1
トークンを貼り付ける
エンコードされた JSON Web Token を入力欄に貼り付けます。デコーダーが自動的にヘッダー・ペイロード・署名へと分割します。
- 2
クレームを読み取る
デコードされたヘッダーとペイロードを整形された JSON で確認し、有効期限や発行時刻などの登録済みクレームを読みやすい日付で確認できます。
- 3
署名を検証する
HMAC トークンの場合は、署名用のシークレットを入力して、署名が有効でトークンが改ざんされていないことを確認します。
- 4
必要な部分をコピーする
整形されたヘッダーやペイロードの JSON をクリップボードにコピーして、テストやドキュメント作成、デバッグに活用できます。
JSON Web Token を理解する: 構造・クレーム・落とし穴
ドットで区切られた 3 つの部分
JSON Web Token は、内部に 2 つのドットを含む 1 本の長い文字列で、それによってヘッダー・ペイロード・署名という 3 つのセグメントに分割されます。最初の 2 つのセグメントはそれぞれ、Base64URL でエンコードされた小さな JSON オブジェクトです。Base64URL は Base64 を URL セーフにした変種で、いくつかの文字を置き換え、パディングを取り除くことで、トークンがヘッダーやクエリ文字列の中でも問題なく扱えるようになっています。3 つ目のセグメントは署名で、最初の 2 つを対象に計算されます。
トークンを貼り付けると、デコーダーがドットで分割し、最初の 2 つの部分を Base64URL でデコードして読みやすい JSON に戻します。ヘッダーとペイロードを、発行者が記述したそのままの形で確認できます。そもそもこれが可能であるという事実こそが、この先のすべての話の核心です。これらのセグメントは単にエンコードされているだけで、暗号化されているわけではないのです。
ヘッダー: アルゴリズムとタイプ
ヘッダーは最も小さな部分です。通常はタイプ(JWT)を宣言し、さらに重要な点として、alg フィールドで署名アルゴリズムを示します。よく使われる値としては、共有シークレットを使う HMAC を用いる HS256、そして秘密鍵で署名し公開鍵で検証する非対称鍵ペアを用いる RS256 や ES256 があります。アルゴリズムは、署名がどのように生成されたか、したがって検証側がどう確認すればよいかを示します。
alg フィールドはセキュリティ上も重要です。アルゴリズムとして none を主張するトークンや、攻撃者が非対称アルゴリズムのトークンを対称アルゴリズムにすり替えて、未熟な検証側に公開鍵を HMAC のシークレットとして使わせようとする手口は、古典的な攻撃です。正しく実装された検証側は、ヘッダーが何と言っていようと盲目的に信用せず、期待するアルゴリズムを固定します。
ペイロードと登録済みクレーム
ペイロードはクレーム、つまりトークンが主張する事柄を運びます。登録済みクレーム名の一式が標準化されており、異なるシステムがその意味について合意できるようになっています。発行者クレーム(iss)はトークンを誰が作成したかを示し、サブジェクトクレーム(sub)はそれが誰または何に関するものか(多くの場合ユーザー ID)を示し、オーディエンスクレーム(aud)は想定される受け取り手を示します。これらと並んで、ロールやテナントといったアプリケーション独自のカスタムクレームも通常見られます。
このデコーダーは、登録済みクレームをラベル付きで人間が読みやすい形で表示するので、暗号のような短い名前をすべて暗記する必要はありません。デバッグ中にトークンをざっと確認し、正しいサービス向けの正しいトークンかどうかを判断するとき、発行者・サブジェクト・オーディエンスが明記されているのを見るだけで事足りることがよくあります。
時刻クレーム: exp、iat、nbf
3 つのクレームがトークンの有効期間を司り、そのすべてが秒単位で測られる Unix タイムスタンプです。ミリ秒ではありません。ミリ秒時刻に慣れた JavaScript 開発者にとって、これは 1000 倍ずれる定番のバグの原因になります。有効期限クレーム(exp)はそれ以降トークンを拒否しなければならない時点、発行時刻クレーム(iat)は作成された時点を記録し、有効開始クレーム(nbf)は有効になる最も早い瞬間を示します。
デコーダーはこれらを読みやすい日付に変換し、お使いのデバイスの時計を基準に、トークンが現在有効か、まだ有効でないか、あるいは期限切れかを伝えます。この最後の点は重要です。コンピューターの時計が狂っていると、有効か期限切れかの判定が誤解を招くことがあり、本番環境ではサーバー間の時計のずれが、発行されたばかりのトークンがまだ有効でないとして拒否される一般的な原因となります。
デコードは検証ではない
これは最も大切に心に刻むべきことです。JWT は誰でもデコードできます。単なる Base64URL だからです。したがって、クレームを読むことでわかるのはトークンが何と言っているかであって、そのトークンが本物かどうかではありません。信頼は、鍵を用いて署名を確認することからのみ生まれます。それによって、トークンがシークレットまたは秘密鍵を保持する者によって発行され、その後改ざんされていないことが証明されます。
HMAC トークン(HS256、HS384、HS512)の場合、このツールはヘッダー・ペイロード・入力されたシークレットから署名を再計算し、トークンの署名と比較して、そのシークレットに対する真正性を確認できます。RS256 や ES256 などの非対称アルゴリズムは発行者の公開鍵が必要なため、ここではデコードは行いますが検証はしません。きわめて重要なこととして、実際の認可の判断はサーバー側で署名を検証しなければなりません。クライアントコードでデコードしただけでトークンのクレームを決して信用してはいけません。
ペイロードは秘密ではない
ペイロードはエンコードされているだけなので、その中のすべてのクレームは、トークンを手にした者には誰にでも丸見えです。ブラウザ、あらゆるプロキシ、そしてユーザー自身も含まれます。JWT は、機密性のない ID 情報や認可情報を置くには最適な場所であり、機密情報を置くには最悪の場所です。パスワード、API シークレット、クレジットカード番号、個人のプライベートな情報を、エンコードが守ってくれると思ってペイロードに入れてはいけません。守ってはくれません。
署名が守るのは完全性であって、機密性ではありません。改ざんは防ぎますが、内容を隠すことは一切しません。ペイロードを読めないように本当に暗号化されたトークンが必要なら、それは別の、より重い仕組み(JWE)です。標準的な JWT は署名されているのであって、暗号化されているわけではありません。シークレットはサーバー側に保管し、トークンの中ではそれを不透明な識別子で参照するようにしてください。
トークンを安全にデバッグする
日々の作業では、このデコーダーは認証フローのデバッグで真価を発揮します。正しいユーザーがサブジェクトクレームに入っているか確認し、リクエストを拒否しているサービスとオーディエンスが一致しているかをチェックし、スコープやロールが存在するかを検証し、有効期限を読んで 401 が単に古くなったトークンによるものかどうかを見極められます。整形されたヘッダーやペイロードをバグ報告やテスト用のフィクスチャにコピーするのもワンクリックです。
すべての処理はブラウザ内でローカルに行われます。トークンも入力したシークレットも、アップロード・記録・保存されることはありません。だからこそ、本番環境の実際のトークンを安全に確認できます。とはいえ、トークンはそれが本来持つ認証情報そのものとして扱ってください。有効で期限切れになっていないトークンは、アカウントへの生きた鍵です。信頼できないツールに貼り付けるのは避け、例として共有するときは期限切れまたはテスト用のトークンを使うようにしましょう。
よくある質問
JSON Web Token(JWT)とは何ですか?
JWT をデコードするとパスワードやシークレットが見えてしまいますか?
ここでの署名検証はどのように行われますか?
exp と iat クレームは何を意味しますか?
入力したトークンはサーバーに送信されますか?
関連ツール
こちらの便利なツールもどうぞ