【入門編】 JWTの署名アルゴリズム(RS256 vs HS256)の選択基準 – Web APIアーキテクチャ・データ連携実践ガイド

鍵の渡し方で運命が変わる?JWTにおけるRS256とHS256の選び方

こんにちは!ネットワークの世界にどっぷりと浸かり、日々パケットの行方を追いかけているエンジニアです。

皆さんはWeb APIを作る際、ユーザーのログイン状態を保持するために「JWT (JSON Web Token)」を使っていますよね? あの怪しげな文字列の羅列、実は「誰が発行したか」を証明する重要な証書なんです。

しかし、いざJWTを実装しようとすると必ずぶつかる壁が「署名アルゴリズム、結局どっちを選べばいいの?」という問題。今回は、対称鍵暗号の HS256 と非対称鍵暗号の RS256 について、ネットワークの現場視点から、身近な例えを交えてじっくり解説していきますね。

—

1. そもそも「署名」って何をしているの?

JWTの署名は、いわば「封筒の封印」です。
中身を誰かが勝手に書き換えていないか、そして本当に信頼できる相手から届いたものかを確認するための「消印」のようなものですね。

この「消印」を押すための「ハンコ」をどう管理するかで、HS256 か RS256 かが決まります。

—

2. 秘密の合言葉「HS256(対称鍵)」

HS256(HMAC with SHA-256)は、「送り主と受け取り主が同じ合言葉(秘密鍵)を知っている」仕組みです。

  • 例え話: 親しい友人同士で「共通の秘密のパスワード」を決めておくようなものです。手紙にそのパスワードを使って暗号印を押し、受け取った方も同じパスワードで「間違いなくアイツからの手紙だ!」と確認します。
  • メリット: 仕組みが単純で、計算も非常に高速です。サーバーのCPU負荷が低いので、トラフィックが爆発的なサービスにはうれしいですね。
  • デメリット: 「秘密鍵」をAPIサーバーと認証サーバーの両方で共有しなければなりません。もしAPIサーバーが100台あったら、その100台すべてに同じパスワードを配る必要があり、どれか1台からパスワードが漏れたら全てが崩壊します。

—

3. 公開と秘密の二刀流「RS256(非対称鍵)」

一方、RS256(RSA Signature with SHA-256)は、「鍵を2つに分ける」仕組みです。

  • 例え話: 認証サーバーだけが「秘密のハンコ(秘密鍵)」を持ち、APIサーバーには「照合用の型紙(公開鍵)」だけを渡すイメージです。APIサーバーは「この型紙にピッタリ当てはまる印があるか」を確認するだけでいいので、ハンコ自体を預かる必要はありません。
  • メリット: APIサーバーにハンコを渡す必要がないため、セキュリティが非常に強固です。万が一APIサーバーがハッキングされても、鍵を盗まれるリスクがありません。
  • デメリット: 鍵の仕組みが複雑なため、HS256 に比べると計算コストが少し高く、サーバーへの負荷は増えます。

—

4. どっちを選ぶべき?インフラ的判断基準

現場で選定する際は、以下の基準で考えるのが鉄則です。

| 比較項目 | HS256 | RS256 |
| :— | :— | :— |
| 鍵の管理 | サーバー間で共有が必要 | 秘密鍵は認証局のみ |
| セキュリティ | 漏洩リスク高(共有のため) | 漏洩リスク極めて低 |
| 負荷 | 軽い(CPUに優しい) | やや重い |
| 推奨環境 | 小規模・マイクロサービス間 | 大規模・分散システム・外部公開API |

「APIゲートウェイ」があるなら、迷わず RS256 を選んでください。
APIゲートウェイは「門番」です。たくさんのサービスから来るリクエストをさばくため、各サービスに秘密鍵を配るなんてことはできません。門番には「公開鍵」だけ持たせて、入ってくるJWTを検証してもらうのが、ネットワーク設計の正解です。

—

5. 実装で意識すること:ヘッダーを見てみよう

JWTをデコードすると、必ず Header と Payload が見えますよね。
ここには、どのアルゴリズムを使ったかが明記されています。

// JWTのヘッダー部分の例
{
  "alg": "RS256", // ここでアルゴリズムを指定します
  "typ": "JWT"
}

もし皆さんがAPIを作るなら、ライブラリを使って以下のように設定します(Pythonの PyJWT の例)。

import jwt

# RS256の場合の署名作成
# 秘密鍵を読み込んで署名します
private_key = open("private_key.pem", "r").read()
payload = {"user_id": 123, "role": "admin"}

token = jwt.encode(payload, private_key, algorithm="RS256")

# APIゲートウェイ側では、公開鍵だけで検証(verify)する
# 秘密鍵が漏れる心配がないので安心!

—

最後に:ネットワークを俯瞰する視点を持って

技術は「何ができるか」だけでなく、「その選択が後の運用でどう跳ね返ってくるか」を考えるのが、真のエンジニアの第一歩です。

「HS256は楽だけど、鍵の管理でいつか泣きを見るかもしれない」
「RS256は少し重いけど、運用はずっと楽になる」

そうやってパケットの運命を想像しながら、設計を楽しんでみてください。最初は難しく感じるかもしれませんが、こうして一つひとつ紐解いていけば、必ず美しいアーキテクチャに辿り着けますよ!

次回は、APIのURL設計における「美しいリソースの捉え方」についてお話ししましょう。それでは、また現場でお会いしましょう!

コメント

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