JWTデコーダ

JWT(ドットで区切られた3つのbase64URL形式の部分からなる)を貼り付けると、デコーダーはヘッダー、ペイロードおよび署名を復号・表示するとともに、検出されたアルゴリズム、ローカル時間に基づくトークン有効期限、およびnbf(発行前)、iat(発行日)、exp(有効期限)が一致しているかどうかを示します。秘密鍵または公開鍵がある場合は、任意で署名の認証も行えます。

JWTをデコードする方法

  1. 1

    トークンを貼り付けます

    `.`(ヘッダー・ペイロード・シグネチャー)で区切られた3つのbase64url文字列。

  2. 2

    復号化されたヘッダーを読みます

    アルゴリズム、タイプ、キーID(`kid`)。アルゴリズムは認証に必要なキーの種類を示します。

  3. 3

    ペイロードを読む

    標準クレーム(`iss`、`sub`、`aud`、`exp`、`iat`、`nbf`、`jti`)に加え、アプリケーションが発行する任意のカスタムクレームが含まれます。

  4. 4

    確認(任意)

    署名が有効であることを確認するには、HMAC秘密(HS256/384/512用)または公開鍵(RS256、ES256など用)を指定してください。

JWTの解剖学

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNjAwMDAwMDAwfQ
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

各セグメントはbase64url(標準的なbase64ではない)で符号化されています。ヘッダーは{"alg":"HS256","typ":"JWT"}のようなJSON形式、ペイロードは{"sub":"1234567890","name":"Alice","iat":1600000000}のようなJSON形式であり、署名はheader.payloadのHMACまたはRSA署名です。

標準クレーム(RFC 7519)

クレーム 名称 説明
iss 発行者 トークンを発行した主体
sub 主体 トークンが対象とする相手
aud 想定利用者 トークンの利用先
exp 有効期限 Unixタイムスタンプ。この時刻を過ぎると拒否される
nbf 有効開始 Unixタイムスタンプ。この時刻より前は拒否される
iat 発行時刻 トークン作成時のUnixタイムスタンプ
jti JWT ID 失効リスト用の一意な識別子

サポートされているアルゴリズム

alg の値 鍵の種類
HS256/HS384/HS512 共有HMACシークレット
RS256/RS384/RS512 RSA公開鍵
ES256/ES384 ECDSA公開鍵
PS256/PS384 RSA-PSS公開鍵
EdDSA / Ed25519 エドワーズ曲線
none 絶対に信頼しないこと、署名のないトークン

alg: none の落とし穴

初期のJWTライブラリは"alg": "none"トークンを許可し、それを無防備に有効と見なしていました。必ず次のようにしてください。

  • アプリケーションが受け入れるアルゴリズムをホワイトリスト化する。
  • alg: noneを無条件で拒否する。
  • 検証コードがRS256を期待しているときにalg: HS256を拒否する(「アルゴリズム混同」攻撃)。

JWTではないもの

  • 暗号化されていない。 ヘッダーとペイロードはbase64でエンコードされているだけで、簡単にデコードできます。JWEで包まない限り、JWTに秘密情報を入れてはいけません。
  • 既定では失効できない。 一度発行されたJWTはexpまで有効です。失効させるにはブラックリスト、または短い有効期限とリフレッシュトークンの併用が必要です。
  • あらゆる用途でセッションクッキーの代替になるわけではない。 サーバー側に保存する不透明なトークンのほうが、しばしばシンプルで安全です。

よくある間違い

  • ヘッダーを信頼する。 kidalgはトークン自体に由来します。侵害されたサーバーはこれらを任意に設定できるため、常に固定のリストと照合して検証してください。
  • nbfiatのずれを無視する。 クロックのずれによりiat > nowが起こり得ます。わずかな許容範囲(30~60秒)を設けてください。
  • JWT全体をログに記録する。 ペイロードにはユーザーID、メールアドレス、権限などのPIIが含まれることが多く、stdoutに出力すべきではありません。
  • 弱いシークレットでHS256を使う。 16文字のシークレットは数分で総当たり攻撃により破られます。少なくとも256ビットのランダムなエントロピーを使用してください。

よくある質問

いいえ。デコード処理はブラウザ内で実行されます。トークンはローカルに保持されます、これは重要ですなぜなら、JWTにはセッションデータ、ユーザーID、権限情報が含まれることが多いからです。

はい。共有されたHMAC秘密またはPEM暗号化された公開鍵を貼り付けると、認証がブラウザ内で行われます。この鍵は決してあなたのデバイスから退出しません。

これは、そのトークンが署名されていないことを意味します。本番環境ではこのようなトークンを決して受け入れてはいけません。なぜなら、それらは容易に偽造できるからです。いくつかの注目を集めたCVEは、デフォルトでalg: noneを受け入れていたライブラリに関連していました。

JWT署名は機密性ではなく、証明性を示します。ヘッダーおよびペイロードはBase64URL形式でエンコードされており、この変換は可逆的です。機密性を確保するには、JWTの周囲にJWE(JSON Web Encryption)を使用するか、ペイロードに機密データを含めないようにしてください。

関連ツール

このツールは他の言語でも利用できます