はじめに
JWT(JSON Web Token)を使った認証を実装する際、最初に選ぶことになるのが署名アルゴリズムです。よく比較されるのがHS256とRS256ですが、この2つは単なる「暗号強度の違い」ではなく、鍵の持ち方そのものが根本的に異なるという点を理解しておくと、どちらを選ぶべきかの判断がしやすくなります。
JWTそのものの基本構造(ヘッダー・ペイロード・署名の3パート構成)については、別記事「Web認証の基礎」で解説しているので、本記事では署名アルゴリズムの違いに絞って整理します。
HS256:対称鍵方式
HS256(HMAC using SHA-256)は、1つの秘密鍵(共有シークレット) を使って署名と検証の両方を行う対称鍵方式です。
- トークンを発行する側(署名する側)と、検証する側が同じ鍵を共有する必要がある
- 鍵が漏洩すると、その鍵を持つ誰もが正規のトークンを偽造できてしまう
- 実装がシンプルで、署名・検証とも同じ鍵を使うだけなので扱いやすい
このため、HS256はトークンの発行者と検証者が同じ信頼境界内(単一のアプリケーション、あるいは鍵を安全に共有できる小規模なサービス群)にいる場合に向いています。
RS256:非対称鍵方式
RS256(RSA using SHA-256)は、秘密鍵で署名し、公開鍵で検証する非対称鍵方式です。
- 署名できるのは秘密鍵を持つ発行者のみ
- 検証する側は公開鍵さえあればよく、秘密鍵を渡す必要がない
- 公開鍵が漏洩しても、それだけでは偽のトークンを作ることはできない(署名には秘密鍵が必須なため)
この性質により、RS256は「発行者は1つだが、検証したい相手(サービス)は複数ある」という構成に向いています。複数の独立したサービスがトークンを検証する必要がある場合や、信頼境界をまたいでトークンを使う場合は、RS256(またはES256などの他の非対称アルゴリズム)が推奨されます。
JWKS:公開鍵を配布する仕組み
RS256を使う場合、検証側は発行者の公開鍵をどうやって入手するのでしょうか。ここで登場するのがJWKS(JSON Web Key Set) です。
発行者(認可サーバー)は、自分の公開鍵を/.well-known/jwks.jsonのようなURLでJSON形式で公開します。JWTのヘッダーにはkid(Key ID)という鍵の識別子が含まれており、検証側は次の手順で検証します。
- JWTのヘッダーから
kidを読み取る - JWKSエンドポイントから公開鍵一覧を取得する
-
kidが一致する公開鍵を選び、その公開鍵でJWTの署名を検証する
この仕組みにより、発行者は鍵をローテーション(定期的に新しい鍵に切り替え)しても、検証側のコードを変更する必要がないというメリットが生まれます。新しい鍵をJWKSに追加し、kidで使い分けるだけで済むためです。
JWKSはHS256では使えません。 対称鍵(共有シークレット)をJWKSのような公開URLに載せてしまうと、そのシークレットを知った第三者が任意のトークンを偽造できてしまうため、原理的に非対称鍵方式(RS256等)専用の仕組みです。
使い分けの目安
| 観点 | HS256が向くケース | RS256/JWKSが向くケース |
|---|---|---|
| 発行者と検証者の関係 | 同じアプリケーション、または鍵を安全に共有できる小規模な範囲 | 発行者は1つ、検証者(サービス)は複数 |
| 鍵の管理 | 検証側にも秘密鍵相当の情報を配置する必要がある | 検証側は公開鍵の取得のみで済み、秘密鍵は発行者だけが持つ |
| 鍵のローテーション | 鍵を変えると検証側の設定も同時に更新が必要 | JWKS経由でkidベースの段階的なローテーションがしやすい |
| パフォーマンス | HMAC計算は軽量 | RSA署名検証はHMACよりCPU負荷が高いが、通常のリクエスト処理(DB問い合わせ等)と比べれば無視できる水準 |
複数の独立したサービス・アプリが同じ認証基盤の発行するトークンを検証する構成(いわゆるSSO・マイクロサービス間認証)では、標準的にRS256とJWKSの組み合わせが採用されます。
まとめ
| 項目 | 内容 |
|---|---|
| HS256 | 対称鍵方式。発行者と検証者が同じ秘密鍵を共有する |
| RS256 | 非対称鍵方式。秘密鍵で署名、公開鍵で検証する |
| JWKS | 発行者が公開鍵を配布するJSON形式の仕組み。kidで鍵を識別し、ローテーションに強い |
| 選び方の目安 | 検証者が複数・信頼境界をまたぐ場合はRS256+JWKS、単一アプリ内で完結するならHS256でも十分 |