JWTとは — 構造・署名・使いどころ

JWT(JSON Web Token)は、JSON で表した情報(クレーム)を、改ざんを検知できる形でやり取りするためのトークン形式です。header.payload.signature の3部構成で、それぞれを base64url でエンコードしてピリオド(.)でつなぎます。サーバ側にセッションを持たないステートレス認証や API の認可で広く使われます。本記事では JWT の構造・各部の中身・署名・「ペイロードは暗号化ではない」という重要な注意点・使いどころ・セキュリティ上の落とし穴を正確に整理します。

結論を先に:JWT の署名は改ざんの検知のためのものであり、内容を隠すものではありません。ペイロードは誰でもデコードして読めるため、機密情報を入れてはいけません。署名方式は共有鍵の HMAC(HS256)か、公開鍵の RSA / ECDSA(RS256・ES256)から用途で選びます。

1. JWT とは — 3部構成と base64url

JWT は、JSON で表したクレーム(claim、主張・情報)を、安全にやり取りするためのコンパクトなトークン形式です。最もよく使われるのは署名付きの形(JWS)で、次の 3 つの部分から成ります。

この 3 部はそれぞれ base64url(URL で安全に扱える Base64 の変種)でエンコードされ、ピリオド(.)で連結されます。つまり全体は次の形です。

base64url(header).base64url(payload).base64url(signature)

実際のトークンは、たとえば次のような 3 つのパートに分かれた文字列になります。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0Iiwicm9sZSI6ImFkbWluIn0.abc123signature

base64url は通常の Base64 から記号を置き換えたもので、+-/_ に変え、末尾の = パディングを省きます。URL やヘッダにそのまま埋め込めるようにするための工夫です。base64url については Base64 の解説記事もあわせてご覧ください。

2. 各部の中身 — ヘッダのクレームと登録クレーム

ヘッダとペイロードは、デコードするとどちらもただの JSON オブジェクトです。中身を順に見ていきます。

ヘッダ(header)

ヘッダは主に 2 つのフィールドを持ちます。

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

ペイロード(payload)と登録クレーム

ペイロードには任意のクレームを入れられますが、仕様で意味が定められた登録クレーム(Registered Claims)がいくつかあります。相互運用のため、これらは名前と意味を守って使います。

クレーム意味備考
iss発行者(issuer)トークンを発行した主体
sub主体(subject)トークンが表す対象(例:ユーザーID)
aud受信者(audience)このトークンを受け取るべき相手
exp有効期限(expiration)この時刻以降は無効。UNIX 秒
nbf有効開始(not before)この時刻より前は無効。UNIX 秒
iat発行時刻(issued at)トークンを発行した時刻。UNIX 秒

例:{ "sub": "1234", "role": "admin", "iss": "https://auth.example.com", "exp": 1924905600 }

このように、ペイロードには「誰が(sub)」「どんな権限を持ち(role などの独自クレーム)」「いつまで有効か(exp)」といった、認可に必要な情報を載せます。

3. 署名 — HMAC(共有鍵)と RSA・ECDSA(公開鍵)

署名は JWT の心臓部です。ヘッダとペイロードを base64url でつないだ文字列に対して署名を計算し、3 番目のパートとして付けます。署名方式は大きく 2 系統あります。

HMAC(HS256 など)— 共有鍵

HMAC は、発行者と検証者が同じ秘密鍵(共有鍵)を持つ方式です。HS256 は SHA-256 を用いた HMAC を指します。署名する側も検証する側も同じ鍵を知っている必要があるため、発行と検証を同じ信頼境界(同一サービス)で行う場合に向きます。

RSA・ECDSA(RS256・ES256 など)— 公開鍵

RSA や ECDSA は公開鍵暗号を使う方式です。発行者は秘密鍵で署名し、検証者は対応する公開鍵で検証します。検証側に秘密鍵を渡さなくてよいため、発行者と検証者が別のとき(例:認証サーバが発行し、複数の API が公開鍵で検証する)に適しています。

署名が保証するのは「完全性」と「真正性」です。受け取った側は署名を検証することで、トークンが正規の発行者によって作られ途中で改ざんされていないことを確認できます。署名が一致しないトークンは無効として拒否します。
観点HMAC(HS256)RSA / ECDSA(RS256・ES256)
鍵の種類共有鍵(1 つの秘密鍵)秘密鍵 + 公開鍵のペア
署名する人共有鍵を持つ者秘密鍵を持つ発行者
検証する人同じ共有鍵を持つ者公開鍵を持つ誰でも
向いている構成発行と検証が同一サービス発行者と検証者が分かれる

4. ペイロードは暗号化ではない — 機密を入れない

JWT で最も誤解されやすい点です。標準的な JWT(JWS)のペイロードは暗号化されていません。base64url は単なるエンコードであり、鍵がなくても誰でもデコードして中身を読めます

ペイロードは「平文」だと考えてください。署名は改ざんの検知のためのものであって、内容を秘匿するものではありません。トークンを手に入れた人は、署名鍵を持っていなくてもペイロードの JSON を読めます。

したがって、次のような機密情報をペイロードに入れてはいけません

もし内容そのものを隠したい場合は、署名だけの JWS ではなく、ペイロードを暗号化する JWE(JSON Web Encryption)を使う必要があります。多くの場面で使われている「JWT」は JWS であり、暗号化はされていない点を必ず押さえてください。

5. 用途 — ステートレス認証と API 認可

JWT の最大の利点は、必要な情報をトークン自身が運ぶ(自己完結している)ことです。これにより、サーバ側でセッションを保持しなくても認証・認可が成立します。

ステートレスである利点の裏返しとして、発行済みトークンを即座に無効化しにくいという課題があります。短い有効期限(exp)と、別途用意するリフレッシュトークンや失効リストの仕組みで補うのが一般的です。

6. セキュリティ注意 — alg=none・有効期限・保管場所

JWT は正しく使えば強力ですが、実装を誤ると認証を丸ごと破られます。代表的な注意点を挙げます。

Free Tool JWT Decoder で実際にデコードする ブラウザ内で JWT のヘッダとペイロードをデコードして中身を確認できます。署名鍵がなくてもペイロードが読めることを、自分の目で確かめられます。

よくある質問(FAQ)

JWTとは何ですか?

JWT(JSON Web Token)は、JSON で表したクレーム(情報)を、改ざんを検知できる形でやり取りするためのトークン形式です。header(ヘッダ)・payload(ペイロード)・signature(署名)の3部構成で、それぞれを base64url でエンコードし、ピリオド(.)で連結した文字列になります。サーバ側にセッションを保持しないステートレスな認証や、API の認可情報の受け渡しに広く使われます。

JWT のペイロードは暗号化されていますか?

いいえ。標準的な JWT(JWS)のペイロードは暗号化ではなく base64url でエンコードされているだけです。鍵がなくても誰でもデコードして中身を読めます。署名は改ざんを検知するためのもので、内容を秘匿するものではありません。したがってパスワードやクレジットカード番号などの機密情報をペイロードに入れてはいけません。内容自体を隠したい場合は、暗号化を行う JWE を使う必要があります。

JWT の署名の役割は何ですか?

署名は、トークンが正規の発行者によって作られ、途中で改ざんされていないことを検証するためのものです。HMAC(HS256 など)では発行者と検証者が同じ共有鍵を持ち、RSA や ECDSA(RS256・ES256 など)では発行者が秘密鍵で署名し、検証者は対応する公開鍵で検証します。署名が一致しないトークンは無効として拒否します。署名は完全性と真正性を保証しますが、ペイロードの内容を暗号化して隠すわけではありません。

← 技術ブログ一覧へ戻る