HS256 と RS256 のどちらを使うか決めるとき、私は「どちらが強いか」から入りません。最初に聞くのは、誰が token を署名できるべきか、誰は verify だけできればよいか、key material を何台の system に配る必要があるかです。
この trust boundary を先に決めると、algorithm 名だけを比較するより判断しやすくなります。
HS256 をどう理解しているか
HS256 は SHA-256 を使う HMAC です。同じ shared secret を signing と verification の両方に使います。
shared secret
├── JWT を sign
└── JWT を verify
つまり API に HS256 secret を渡して verify させると、その API は原理上 token を sign できる材料も持つことになります。
小さく閉じた trust boundary では合理的です。しかし verifier が増えるほど、secret 配布の意味が重くなります。
RS256 をどう理解しているか
RS256 は RSA PKCS#1 v1.5 + SHA-256 の署名です。
private key -> sign
public key -> verify
API には public key だけを配ればよく、private signing capability を渡さずに verification できます。
そのため、1 つの identity provider が多くの独立 API に token を発行する構成では、私は RS256 のような asymmetric model を選びやすいです。
最初の判断基準は「誰が token を mint できるか」
1 サービス内で sign と verify が完結し、secret を狭い範囲に保てるなら HS256 はシンプルです。
一方、central authorization server が多数の API に token を発行する場合、API は verify だけできればよく、token を新規発行できる必要はありません。この要件なら public/private key を分離できる RS256 が自然です。
私はこれを algorithm 選択ではなく signing authority の配布設計 と考えます。
HS256 が合うと考える条件
- signer と verifier が同じ狭い trust boundary にある。
- secret の配布先を少数に保てる。
- public verification key を公開する必要がない。
- 運用の単純さを優先したい。
- secret holder 全員に signing capability があることを意図的に受け入れている。
ただし secret は強い random value にします。RFC 8725 は human-memorable な弱い HMAC secret に対する offline guessing の危険を指摘しています。
RS256 を選びやすい条件
- central IdP が token を sign する。
- 多数の resource server が verify する。
- verifier に signing capability を渡したくない。
- public key を広く配布したい。
- JWKS を使って key rotation したい。
public key が漏れても、それだけで valid RS256 signature を作れる設計ではありません。高価値 credential は private key 側です。
「RS256 は常に安全」とは考えない
どちらも運用を間違えれば危険です。
HS256 の典型的な問題:
- secret が短い / 推測しやすい。
- 多数の service に同じ secret をコピーする。
- verifier compromise が signing compromise になる。
- secret の raw bytes / Base64 解釈が system 間で違う。
- token が指定した algorithm を無条件に受け入れる。
RS256 の問題:
- private key 管理が弱い。
- arbitrary public key を信頼する。
- rotation 後に stale JWKS を使う。
- issuer / audience validation をしない。
- untrusted
algを policy として扱う。
大切なのは、自分の architecture に合う key model を選び、その model を正しく運用することです。
algorithm は application 側で pin する
私は token header に verifier policy を決めさせません。
例えば application が RS256 を期待するなら:
allowed algorithms = [RS256]
を設定し、token が HS256 を名乗ったからといって自動切り替えしません。RFC 8725 も supported algorithm set を明示することを推奨しています。
HS256 の key distribution をどう見るか
3 つの API が同じ HS256 token を verify するとします。
auth server -- shared secret --> API A
-- shared secret --> API B
-- shared secret --> API C
4 system が同じ secret を知るなら、4 system とも署名を作れる材料を持ちます。HMAC が壊れているのではなく、trust relation が広いということです。
それが許容できないなら、secret を verification-only と呼んで済ませず architecture を変えます。
RS256 の key distribution
auth server keeps private key
|
+--> API A gets public key
+--> API B gets public key
+--> API C gets public key
この分離は「発行者は 1 つ、検証者は多数」という構成と相性が良く、JWKS による public-key publication / rotation にもつながります。
kid と JWKS の役割
rotation する RS256 token では header に:
{
"alg": "RS256",
"kid": "2026-key-03"
}
が入ることがあります。私は kid を trusted JWKS の中から候補 key を選ぶ hint として使います。
kid 自体は trust の証明ではありません。詳しい選択フローは JWT kid ガイド と JWKS Validator で確認します。
どちらも key なしで decode はできる
HS256 でも RS256 でも、通常の署名付き JWT の header / payload は暗号化されません。そのため JWT デコーダー で key なしに読むことができます。
key が必要になるのは「内容を読む」から「trusted signer が署名したと確認する」段階です。秘密鍵なしで JWT をデコードするガイド でもこの境界を詳しく説明しています。
私の HS256 checklist
- secret は十分に強く random か。
- 何 system に配布するか。
- verifier 全員に signing capability があることを許容するか。
- UTF-8 / Base64 等、secret bytes の解釈は一致しているか。
- allowed algorithm を pin しているか。
- rotation 後の古い secret が残っていないか。
私の RS256 checklist
- private key はどこで保護されるか。
- public key はどの trust path で配布されるか。
- rotation 時に
kidでどう key を選ぶか。 - key source は expected issuer に bind されているか。
- unexpected algorithm を拒否するか。
- signature 後に issuer、audience、time claims を検証するか。
署名エラーが出たら、algorithm を変えて通るものを探すのではなく JWT invalid signature ガイド の順番で原因を追います。
私が使う最終判断
- HS256: shared-secret trust boundary が本当に狭く、secret holder 全員を signer として信頼できるとき。
- RS256: 1 signer / many verifiers にして、verification と signing authority を分離したいとき。
私にとって HS256 vs RS256 の本質は、hash 名ではなく key ownership と trust distribution です。