JWT ガイド

HS256 と RS256 を選ぶときに私が見る JWT の信頼境界

HS256 と RS256 を単純な強弱で比べず、signer、verifier、鍵配布、rotation、権限分離の観点から選ぶ実務的な判断方法を解説します。

著者: JWTDecoder.tools最終確認 2026-09-13

編集上の表現について:一人称の記述は JWTDecoder.tools の検証済みワークフローを示すもので、発行者・組織著者は JWTDecoder.tools です。

HS256 ↔ RS256 signing architecture
HS256: shared secret · RS256: private key → sign, public key → verify

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 です。

出典・参考資料

関連ガイド