【入門編】 JWT(JSON Web Token)のヘッダーフィールド(alg, typ, kid)の役割 – Web APIアーキテクチャ・データ連携実践ガイド

認証の「身分証明書」を読み解く:JWTのヘッダーが語る、隠されたストーリー

こんにちは!ネットワークの世界に飛び込んで間もない皆さん、あるいはAPIの設計で「結局このヘッダーって何のためにあるの?」と立ち止まってしまった皆さん。

今日は、Web APIのセキュリティを支える「JWT(JSON Web Token)」という魔法の切符について、その頭の部分――「ヘッダー」に焦点を当ててお話しします。

JWTは、APIとやり取りする際に「私は誰か」を証明する身分証のようなものです。でも、ただの文字列に見えるこのJWT、実は中身が細かくルール化されています。さあ、ネットワークの深淵を少しだけ覗いてみましょう!

—

1. JWTのヘッダーは「封筒の表書き」

JWTは大きく分けて「ヘッダー」「ペイロード(中身)」「署名」の3つのパーツで構成されています。このうち一番先頭にあるヘッダーは、いわば「封筒の表書き」です。

郵便配達員さんが、宛先や速達かどうかを封筒の表を見て判断するように、サーバー側もこのヘッダーを見て「どうやってこのトークンを解読すればいいか」を判断します。

ヘッダーの中には、主に3つの重要なフィールドがあります。

alg (Algorithm):どうやって封を閉じたか

「この封筒、どんな鍵で封印したの?」を伝える役割です。HS256(共通鍵)やRS256(公開鍵)といった暗号方式が指定されます。これがないと、サーバーは鍵をどう使えばいいか分かりません。

typ (Type):何が入っているか

「これはJWTという種類のトークンですよ」という宣言です。基本的には JWT という値が入ります。これは「身分証です」という種別を明示して、誤用を防ぐためのラベルのようなものです。

kid (Key ID):どの鍵を使うべきか

ここが重要です!公開鍵暗号を使っている場合、サーバーはたくさんの公開鍵を管理しています。「俺の持っている鍵のうち、どれを使えばこの封筒が開けられるの?」という問いに対する答えが kid です。特定の鍵を指し示す「指紋」のようなものですね。

—

2. 禁断の「alg: none」攻撃を知っていますか?

ここで、ネットワークエンジニアとして一つ、皆さんに知っておいてほしい「過去の教訓」があります。

昔々、あるライブラリで alg の値を none に設定すると、「署名の検証をスキップする」という脆弱性が見つかりました。

想像してみてください。誰でも中身を書き換えられる郵便物に、わざわざ「封印なし(none)」と書かれた封筒が届いたらどうしますか? 悪意あるユーザーは、トークンの中身を admin: true に書き換えて、ヘッダーに alg: none と書き込んでサーバーに送りつけました。結果、サーバーは「あ、署名チェックしなくていいんだね!」と鵜呑みにしてしまったのです。

対策:厳格なホワイトリスト運用

この攻撃を防ぐには、サーバー側で「受け入れるアルゴリズムを明示的に指定する」ことが鉄則です。

# 安全なJWT検証の例(Python/PyJWTのイメージ)
import jwt

# サーバー側が許可するアルゴリズムのみをリスト化しておく
allowed_algorithms = ["RS256"]

try:
    # 署名アルゴリズムをハードコードで制限し、noneを一切受け付けない
    decoded = jwt.decode(
        token, 
        public_key, 
        algorithms=allowed_algorithms
    )
except jwt.InvalidAlgorithmError:
    print("不正なアルゴリズムが指定されました!")

このように、「何でも屋」ではなく「特定の鍵だけを信じる」姿勢が、ネットワークの安全を守るのです。

—

3. 実践:美しいトークンの設計

実務でJWTを扱う際は、ヘッダーを以下のように構成するのが「美しい設計」とされています。

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "v1-2023-production-key"
}
  • alg: RS256 などの非対称鍵方式を採用することで、鍵の漏洩リスクを最小限にします。
  • typ: JWT を指定し、仕様に則っていることを明確にします。
  • kid: バージョン管理されたIDを付与することで、鍵のローテーション(定期的な変更)がスムーズに行えるようにします。

—

最後に:ネットワークは「信頼の積み重ね」

alg, typ, kid。これらは単なる文字列ではなく、サーバーとクライアントの間で交わされる「信頼の握手」です。

ネットワークのトラブルシューティングをしていると、パケットキャプチャの中でこうした小さなヘッダーの不一致が、巨大な障害を引き起こしている現場に何度も遭遇します。そんなとき、この「封筒の表書き」という概念を知っているだけで、解決への糸口は格段に見つけやすくなります。

皆さんも、APIを設計する際はぜひ、この小さなヘッダーに「安全への願い」を込めてみてください。それが、堅牢なシステムを構築する第一歩になります。

それでは、また次回の深淵でお会いしましょう!Happy Hacking!

コメント

タイトルとURLをコピーしました