JWT署名アルゴリズム RS256とHS256のセキュリティ・鍵管理比較
JWT Security Backend Authentication
結論
複数サービス構成では RS256 + JWKS を採用し、検証側でアルゴリズムを明示的に固定します。
// RFC 7519/7517仕様:検証側APIでの安全な JWT 検証コード(Algorithm Confusion 防御)
import jwt from 'jsonwebtoken';
import jwksClient from 'jwks-rsa';
const client = jwksClient({
jwksUri: 'https://auth.example.com/.well-known/jwks.json',
});
function getKey(header: any, callback: any) {
client.getSigningKey(header.kid, (err, key) => {
callback(null, key?.getPublicKey());
});
}
// ⭕ アルゴリズムを RS256 に明示固定(HS256 へのすり替え偽造攻撃をブロック)
jwt.verify(token, getKey, { algorithms: ['RS256'] }, (err, decoded) => {
if (err) console.error('認証失敗:', err);
});
RFC 7519公式仕様:アルゴリズムと鍵管理の比較マトリクス
| 評価軸 | HS256 (HMAC with SHA-256) | RS256 (RSA Signature with SHA-256) |
|---|---|---|
| 鍵の構造 | 単一の共通秘密鍵 (Symmetric) | 秘密鍵 / 公開鍵のペア (Asymmetric) |
| 検証側の鍵保持 | 署名時と同一の秘密鍵が必要 | 公開鍵(JWKS)のみで検証可能 |
| 鍵漏洩時の影響 | 検証側から漏れると偽造トークン発行可能 | 公開鍵が露出しても署名不可(安全) |
| 鍵のローテーション | 全サービスの一斉再起動が必要 | /.well-known/jwks.json で自動取得 |
実際に起こる脆弱性事故:Algorithm Confusion(アルゴリズム混同)攻撃
JWTセキュリティ監査で最も有名な脆弱性が Algorithm Confusion 攻撃 です。
認可サーバーが RS256(公開鍵暗号)でトークンを発行している環境において、検証側ライブラリが JWT ヘッダーの "alg" 判定を動的許可している場合、攻撃者がネット上で公開されている「公開鍵文字列」を共通鍵(HS256)として使用し、管理者権限(admin)の偽造 JWT を自作して送信する攻撃 が成立します。
検証側が「公開鍵」を「HS256の共通鍵」として誤認して検証をパスさせてしまい、完全な認証スルー(特権昇格事故) が発生します。
防御・運用手順
- 認証サーバー側で RSA 2048bit 秘密鍵を管理し、
/.well-known/jwks.json(RFC 7517)で公開鍵を配信する - トークンを検証する各 API サービス側では、JWT ヘッダーの
"alg"を盲信せず、jwt.verify(token, key, { algorithms: ['RS256'] })のように受け入れるアルゴリズムをコード上で明示的に固定指定する - 単一サーバー内で完結する小規模API以外で
HS256を安易に使用しない