JWT (JSON Web Token) とは?
JWT (JSON Web Token) は、情報のやり取りを安全に行うために、情報をJSONオブジェクトとしてコンパクトにまとめ、デジタル署名を施したトークンの規格(RFC 7519)です。 主にWebアプリケーションのセッション管理や、API認可(OAuth 2.0 / OpenID Connect)における「アクセストークン」「IDトークン」として広く利用されています。
一見、単なるランダムな英数字の羅列のように見えますが、内部にはエンコードされた明確なデータ構造が存在します。
JWTの3つの構造
JWTは、ドット(.)で区切られた以下の3つのセクションで構成されています。
[ヘッダー(Header)].[ペイロード(Payload)].[署名(Signature)]

1. ヘッダー (Header)
トークンの種類(通常は "JWT")と、署名に使用しているアルゴリズム(例: HMAC-SHA256 を示す "HS256" や RSA を示す "RS256")が記述されています。
{
"alg": "HS256",
"typ": "JWT"
}
2. ペイロード (Payload)
やり取りしたいデータ本体(ユーザーID、ユーザー名、権限情報など)が含まれています。これらJSONオブジェクトの各項目は「クレーム(Claims)」と呼ばれ、JWT規格で事前定義された項目(有効期限 exp、発行者 iss など)と、独自に定義する項目(userId など)があります。
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"exp": 1784632800
}
3. 署名 (Signature)
トークンが途中で改ざんされていないこと、および信頼できる発行元から送られたものであることを検証するためのセクションです。 エンコードされたヘッダーとペイロードをドットで結合し、指定のアルゴリズム(ヘッダーに記載されたもの)と「秘密鍵(シークレットキー)」を用いて計算されます。
【最重要】JWTは「暗号化」されていないという誤解
JWTを導入する上で、最も多く発生するセキュリティ上の誤解が、「JWTは暗号化されているため、第三者に中身を見られない」という思い込みです。
ヘッダーとペイロードは、暗号化されているわけではなく、単に Base64URL というアルゴリズムで文字列にエンコードされているだけ です。 Base64URLのデコードは特別な鍵を必要とせず誰でも瞬時に行えるため、**「JWTのヘッダーとペイロードは平文(誰でも読める状態)である」**と認識してください。
[!CAUTION] JWTのペイロードの中に、パスワードやクレジットカード番号、機密性の高い個人情報(メールアドレスや本名など)を生のまま含めないでください。JWTが漏洩した瞬間に、それらの情報がすべて第三者に露出することになります。
JWTの主な目的は、データの「秘密性(隠すこと)」ではなく、**「整合性(改ざんされていないことの証明)」と「送信元証明(信頼できるサーバーが発行したことの証明)」**にあります。
Generator & Decoder の使い方
JWT Decoder の役割
受け取ったJWTがどんな中身を持っているかデバッグしたい場合に使用します。 暗号化されていないため、トークンを貼り付けるだけで、ドットで分割されたそれぞれのセクションがBase64URLデコードされ、整形されたJSONとして中身を確認できます。
- Torinoa Toolsで試す: JWT Decoder
JWT Generator の役割
テスト用のモックトークンを発行したい場合などに使用します。 ヘッダー、ペイロード、署名キー(Secret)を入力し、アルゴリズムを選択することで、有効な署名がついたJWTを即座に生成できます。
- Torinoa Toolsで試す: JWT Generator
[!WARNING] Web上の一部のJWTジェネレーターは、入力された秘密鍵やトークンデータを開発者のサーバーに送信して処理している場合があり、情報漏洩のリスクがあります。Torinoa Toolsでは、データの処理は完全にユーザーのブラウザ上(ローカル)で行われますが、それでも安全のため本番環境の秘密鍵は入力しないようにしてください。
JWTを安全に運用するための注意点
1. 署名鍵(Secret)を強固にする
HMAC(HS256など)を使用する場合、署名鍵が短い、または推測しやすい文字列であると、攻撃者にハッシュの総当たりをされ、秘密鍵を特定されてしまいます。鍵が特定されると、攻撃者は自由に偽装された管理権限トークンを作成して不正アクセスできるようになります。十分に長くランダムなキーを設定してください。
2. 有効期限(exp)を必ず設定する
JWTはサーバーサイドで無効化することが難しい(セッションのように状態を持たないステートレス運用の目的があるため)という性質があります。漏洩時の被害を最小限に抑えるため、有効期限(exp クレーム)は数分〜数時間程度と短めに設定し、長期のセッション維持にはリフレッシュトークンを併用する設計が一般的です。
3. アルゴリズム(alg)の検証を行う
一部の古いJWT検証ライブラリには、ヘッダーの alg を "none"(署名なし)に書き換えられたJWTを受け入れてしまう脆弱性(none algorithm 攻撃)が存在しました。ライブラリを使用する際は、必ず許可するアルゴリズムを明示的に指定して検証するようにプログラムを実装してください。