Skip to content

RFC 7519 - JSON Web Token (JWT)

概要

RFC 7519 は、JSON Web Token(JWT) を定義する標準仕様である。JWT は、2つの当事者間でクレーム(claims)をコンパクトかつ URL-safe な方法で表現・転送するためのメカニズムを提供する。

HTTP ヘッダや URI クエリパラメータなど、スペースに制約のある環境での使用を想定して設計されており、クレームは JSON オブジェクトとして表現され、JSON Web Signature(JWS)によるデジタル署名・MAC、または JSON Web Encryption(JWE)による暗号化によって保護される。

解決する課題

JWT 以前は、セキュリティトークンの標準形式として SAML(Security Assertion Markup Language)や SWT(Simple Web Token)が使われていた。しかし以下の課題があった。

  • SAML の冗長性: XML ベースで構造が複雑・サイズが大きく、HTTP ヘッダや URI での使用に適さない
  • SWT の表現力の乏しさ: 型付けされた値や複雑なデータ構造を表現できない
  • 相互運用性の欠如: 統一された標準がなく実装間での互換性が低い

JWT は JSON のシンプルさとコンパクト性を活かし、特に OAuth 2.0 などの Web 系プロトコルでの利用に最適化されたトークン形式を提供する。

主要概念・用語

用語説明
JWTJSON Web Token。クレームセットを表現するコンパクトな URL-safe トークン
クレーム(Claim)エンティティ(通常はユーザー)や追加情報に関する主張
JWT クレームセットクレームを含む JSON オブジェクト
JOSE ヘッダー暗号化操作に関するメタデータを含む JSON オブジェクト
JWSJSON Web Signature。JWT を署名・MAC で保護する仕様(RFC 7515)
JWEJSON Web Encryption。JWT を暗号化で保護する仕様(RFC 7516)
NumericDate1970-01-01T00:00:00Z UTC からの経過秒数を表す JSON 数値
StringOrURI文字列、またはコロン(:)を含む場合は URI として解釈される値
Unsecured JWTアルゴリズムに "none" を指定した署名なし JWT

JWT の構造

JWT は Base64url エンコードされた 3 つの部分をピリオド(.)で連結した形式を取る。

BASE64URL(JOSE ヘッダー) . BASE64URL(ペイロード) . BASE64URL(署名)

具体例

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JOSE ヘッダー

暗号化操作のメタデータを含む JSON オブジェクト。

json
{
  "alg": "HS256",
  "typ": "JWT"
}

主要なパラメータ:

パラメータ説明
alg使用する署名・暗号化アルゴリズム(必須)
typメディアタイプ。JWT には "JWT" を推奨
ctyコンテンツタイプ。Nested JWT の場合は "JWT" を指定

ペイロード(JWT クレームセット)

クレームを含む JSON オブジェクト。クレームは「登録済みクレーム名」「パブリッククレーム名」「プライベートクレーム名」の 3 種類に分類される。

json
{
  "iss": "https://example.com",
  "sub": "user123",
  "aud": "https://api.example.com",
  "exp": 1735689600,
  "iat": 1735686000,
  "jti": "abc123"
}

署名

JWS の場合、JOSE ヘッダーとペイロードに対して指定されたアルゴリズムで計算した値。JWE の場合は暗号化された内容となる。

クレームの詳細

登録済みクレーム名

IANA に登録された標準クレーム。いずれもオプションだが、使用する場合は定義に従った意味を持つ。

クレーム名称説明
issIssuerStringOrURIJWT を発行したプリンシパルの識別子
subSubjectStringOrURIJWT の主体(ユーザー等)の識別子。発行者のコンテキスト内で一意
audAudienceStringOrURI または配列JWT の受信対象。処理するシステムは自身が対象か確認する
expExpiration TimeNumericDateこの時刻以降は JWT を受け付けない(有効期限)
nbfNot BeforeNumericDateこの時刻より前は JWT を受け付けない(有効開始時刻)
iatIssued AtNumericDateJWT の発行時刻。年齢の判定に使用可能
jtiJWT ID文字列JWT の一意識別子。リプレイ攻撃の防止に使用

パブリッククレーム名

独自に定義できるが、衝突を防ぐため IANA「JSON Web Token Claims」レジストリへの登録、またはドメイン名・OID・UUID などのコリジョン耐性のある名前の使用が求められる。

プライベートクレーム名

発行者と受信者の間で独自に定義するクレーム。名前衝突のリスクがあるため、外部との共有には注意が必要。

プロトコルフロー

JWT の生成と検証フロー

JWT の作成手順(Section 7.1)

  1. JWT クレームセットを含む JSON オブジェクトを作成する
  2. その UTF-8 表現をメッセージとして準備する
  3. JOSE ヘッダーを作成する(JWS または JWE の仕様に従う)
  4. JWS または JWE として処理する
  5. ネストが必要な場合は手順 3 に戻り、新しい JOSE ヘッダーで "cty": "JWT" を指定する
  6. 最終的な JWT を取得する

JWT の検証手順(Section 7.2)

  1. JWT が少なくとも 1 つのピリオド(.)を含むことを確認する
  2. JOSE ヘッダーを Base64url デコードし、有効な JSON であることを確認する
  3. JOSE ヘッダーのパラメータを検証する
  4. JWS か JWE かを判定する("enc" パラメータの有無で識別)
  5. 該当する仕様に従い署名の検証または復号を行う
  6. ネストされた JWT の場合は再帰的に処理する
  7. ペイロードを Base64url デコードし、有効な JSON であることを確認する
  8. expnbfissaud 等の登録済みクレームを検証する

詳細解説

JWS vs JWE

JWT は保護方式によって 2 つの形態がある。

種別特徴ヘッダー例
JWS署名・MAC による完全性保護。ペイロードは Base64url されているだけで可読{"alg":"HS256"}
JWEペイロードを暗号化。機密情報の保護が可能{"alg":"RSA-OAEP","enc":"A256GCM"}
Nested JWTJWS を JWE で包む。署名のプライバシーも保護{"alg":"RSA-OAEP","enc":"A256GCM","cty":"JWT"}

Unsecured JWT

アルゴリズムに "none" を指定した場合、署名なしの JWT となる。JWT 外部のセキュリティ機構(TLS など)によって保護されている場合に使用される。

json
{
  "alg": "none"
}

この形式は署名値が空文字列となり、トークンの末尾のピリオドの後に何も付かない。実装では "none" の受け入れを適切に制限する必要がある。

NumericDate の扱い

有効期限などの時刻値は NumericDate(UNIX エポックからの経過秒数)で表現する。うるう秒は考慮しない。

exp: 1735689600  →  2026-01-01T00:00:00Z

クレームの複製(JWE での特殊ケース)

JWE(暗号化 JWT)において、isssubaud のクレームを JOSE ヘッダーに複製することが許可されている。これにより、復号前にこれらのクレームを確認できる。ただし、ヘッダー内の値とペイロード内の値の一致を必ず検証しなければならない。

必須・推奨アルゴリズム

RFC 7519 では以下のアルゴリズムサポートを規定している(詳細は RFC 7518 / JWA を参照)。

アルゴリズム種別要件
HS256(HMAC + SHA-256)JWS必須(MUST)
noneJWS(Unsecured)必須(MUST)
RS256(RSASSA-PKCS1-v1_5 + SHA-256)JWS推奨(RECOMMENDED)
ES256(ECDSA + P-256 + SHA-256)JWS推奨(RECOMMENDED)

セキュリティに関する考慮事項

信頼の確立

JWT の内容を信頼決定に使用するためには、暗号学的に保護されており、かつその保護に使用されたキーが正当な発行者の制御下にあることを確認する必要がある。署名検証に使用するキーの出所の確認が不可欠である。

アルゴリズムの混同攻撃(Algorithm Confusion)

検証側が期待するアルゴリズムを明示的に指定せず、ヘッダーの alg パラメータをそのまま使用すると、攻撃者が意図しないアルゴリズムで署名を検証させる「アルゴリズム混同攻撃」が発生する可能性がある。

例:RS256 で署名を検証するシステムに対し、公開鍵を HMAC の共有鍵として使い "alg":"HS256" のトークンを送りつける攻撃。

対策:検証側は許可するアルゴリズムを事前に設定し、ヘッダーの値に関わらずそれを使用する。

"none" アルゴリズムの取り扱い

Unsecured JWT("alg":"none")を意図せず受け入れる実装が存在すると、署名検証をバイパスされる危険がある。"none" を受け入れる場面を明示的に制限する必要がある。

署名と暗号化の順序

機密性と完全性の両方が必要な場合は、署名してから暗号化する(Sign then Encrypt) 順序が推奨される。これにより:

  • 暗号化によって署名者の身元が保護される
  • 暗号文の外側からは署名者情報が漏洩しない

有効期限の検証

expnbf の検証は必須である。クロックスキュー(サーバー間の時刻のずれ)を考慮した若干のマージン(数分程度)を設けることが一般的だが、マージンは最小限に留めるべきである。

jti によるリプレイ攻撃対策

一度使用した jti を記録し、同じ jti を持つ JWT を拒否することでリプレイ攻撃を防ぐことができる。ステートレスな JWT の利点を損なうが、高セキュリティな場面では有効な対策となる。

機密クレームの保護

署名のみの JWS では、ペイロードは誰でも読める(Base64url は暗号化ではない)。個人情報や機密情報を含む場合は、JWE による暗号化が必要である。

関連仕様

仕様内容
RFC 7515 - JWSJSON Web Signature。JWT の署名・MAC 処理の基盤
RFC 7516 - JWEJSON Web Encryption。JWT の暗号化処理の基盤
RFC 7517 - JWKJSON Web Key。JWT の署名・暗号化に使用する鍵の表現形式
RFC 7518 - JWAJSON Web Algorithms。JWT で使用可能なアルゴリズムの定義
RFC 6749 - OAuth 2.0JWT はアクセストークンやアサーションとして OAuth 2.0 と組み合わせて広く使われる
RFC 9068JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens
OpenID Connect CoreID トークンとして JWT を使用

参考文献