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の共通鍵」として誤認して検証をパスさせてしまい、完全な認証スルー(特権昇格事故) が発生します。


防御・運用手順

  1. 認証サーバー側で RSA 2048bit 秘密鍵を管理し、/.well-known/jwks.json(RFC 7517)で公開鍵を配信する
  2. トークンを検証する各 API サービス側では、JWT ヘッダーの "alg" を盲信せず、jwt.verify(token, key, { algorithms: ['RS256'] }) のように受け入れるアルゴリズムをコード上で明示的に固定指定する
  3. 単一サーバー内で完結する小規模API以外で HS256 を安易に使用しない