FIG-035

JWT — 読めるのに偽造できない通行証

セキュリティ 2026.06.22 公開 読了 約11分

ログイン後、サーバーは「この人はaliceさん」と毎回データベースに問い合わせる代わりに、本人だと証明する通行証を発行して持たせることがあります。その代表が JWT(JSON Web Token)。中身(誰なのか・権限は何か)が誰でも読めるのに、1文字でも書き換えると無効になるという不思議なチケットです。

秘密は末尾の署名(ハンコ)にあります。サーバーだけが知る秘密鍵で「ヘッダー+中身」からハンコを計算してくっつける。受け取ったサーバーは同じ計算をやり直し、ハンコが一致するか確かめます。下の図1で中身を書き換えてから検証してみてください。ハンコが合わなくなってブブーと弾かれます。

いまの通行証(JWT) — ヘッダー.中身.署名 の3つを . で繋いだ文字列
..
中身(payload) — 自由に書き換えられる
サーバーだけが知る秘密鍵
🔑 server-secret-key
🎫
まず「サーバーが発行」を押して通行証をもらおう
発行すると、いまの中身に対する正しいハンコ(署名)が付きます。
図1 — 中身は丸見えでも、秘密鍵を知らない人は正しいハンコを作れない(署名はHS256で実計算)

なぜ「読めるのに偽造できない」のか

JWTの中身は単にBase64でエンコードしただけで、暗号化はされていません。だから誰でもデコードして読めます(パスワードなど秘密を入れてはいけないのはこのため)。守っているのは署名です。署名は「ヘッダー+中身+秘密鍵」を HMAC-SHA256 などのハッシュにかけた値。秘密鍵を知らない攻撃者は、中身を書き換えてもそれに合う新しいハンコを計算できません。だから検証側で「中身から計算し直したハンコ」と「付いてきたハンコ」がズレ、改ざんが即バレます。

この仕組みのおかげで、サーバーはトークンをその場で検証するだけで本人確認でき、セッション情報をサーバー側に溜め込まなくて済みます(ステートレス)。一方で、一度発行したトークンは有効期限が来るまで取り消しにくい弱点もあります。だから exp(失効時刻)を短めにし、必要なら別途失効リストで管理します。

用語ミニ辞書
JWT
ヘッダー・中身・署名の3部をドットで繋いだ通行証。中身は読めるが改ざんは検知できる。
署名(HMAC)
秘密鍵を混ぜて計算するハンコ。鍵を知らないと正しい値を作れない。
ステートレス
サーバーが個別のセッションを保持せず、トークン自体で本人確認できる方式。
exp(有効期限)
トークンの失効時刻。盗まれたときの被害を抑えるため短めにするのが定石。

まとめ

JWTは「中身は公開、ハンコは秘密鍵で」という割り切りで成り立つ通行証です。中身を1文字でも書き換えるとハンコが合わなくなり、秘密鍵を持たない攻撃者は正しいハンコを作れない —— だから読めても偽造はできません。図1で roleadmin に改ざんしてから検証し、サーバーが偽造を見抜く瞬間を確かめてみてください。