JWK
暗号鍵を JSON 形式で表現する標準仕様で、JWT の署名検証に使用される
JWK とは
JWK (JSON Web Key) は、暗号鍵を JSON 形式で表現する標準仕様 (RFC 7517) である。JWT の署名検証に使う公開鍵を、HTTP エンドポイント経由で安全に配布するために広く使われている。
従来、公開鍵の配布は PEM ファイルの手動コピーや X.509 証明書の配布に依存していた。JWK はこれを JSON + HTTPS という Web ネイティブな方式に置き換え、鍵のローテーションや複数鍵の管理を自動化可能にした。OAuth 2.0 / OpenID Connect のエコシステムで事実上の標準となっている。
JWK の構造
JWK の構造の例を示す。
{
"kty": "RSA",
"kid": "2026-03-key-1",
"use": "sig",
"alg": "RS256",
"n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2...",
"e": "AQAB"
}
| フィールド | 意味 | 例 |
|---|---|---|
kty |
鍵の種類 (Key Type) | RSA, EC, OKP |
kid |
鍵の識別子 (Key ID) | 任意の文字列。JWT ヘッダーの kid と照合 |
use |
用途 | sig (署名), enc (暗号化) |
alg |
アルゴリズム | RS256, ES256 |
n, e |
RSA 公開鍵のパラメータ | Base64url エンコードされた値 |
kid が最も重要なフィールドだ。JWT を受け取ったサーバーは、JWT ヘッダーの kid と JWKS 内の kid を照合し、どの鍵で署名検証すべきかを特定する。
JWKS エンドポイント
認証プロバイダーは、公開鍵のセットを JWKS (JSON Web Key Set) エンドポイントで公開する。
# Cognito
https://cognito-idp.ap-northeast-1.amazonaws.com/{userPoolId}/.well-known/jwks.json
# Auth0
https://{tenant}.auth0.com/.well-known/jwks.json
# Google
https://www.googleapis.com/oauth2/v3/certs
レスポンスは keys 配列に複数の JWK を含む。
{
"keys": [
{ "kid": "key-1", "kty": "RSA", "use": "sig", ... },
{ "kid": "key-2", "kty": "RSA", "use": "sig", ... }
]
}
複数の鍵が含まれるのは、鍵のローテーション中に新旧両方の鍵が有効である必要があるためだ。
JWT 署名検証の流れ
- クライアントが JWT をサーバーに送信する
- サーバーは JWT ヘッダーから
kidを取得する - JWKS エンドポイントから公開鍵セットを取得する (キャッシュがあればキャッシュから)
kidが一致する JWK を見つける- その公開鍵で JWT の署名を検証する
- 署名が有効なら、JWT のペイロード (claims) を信頼する
import jwt from 'jsonwebtoken';
import jwksClient from 'jwks-rsa';
const client = jwksClient({
jwksUri: `https://cognito-idp.ap-northeast-1.amazonaws.com/${userPoolId}/.well-known/jwks.json`,
cache: true, // JWKS をキャッシュ
cacheMaxAge: 600000, // 10分間キャッシュ
});
function getKey(header: jwt.JwtHeader, callback: jwt.SigningKeyCallback) {
client.getSigningKey(header.kid!, (err, key) => {
callback(err, key?.getPublicKey());
});
}
jwt.verify(token, getKey, { algorithms: ['RS256'] }, (err, decoded) => {
if (err) throw new Error('JWT 検証失敗');
// decoded にペイロードが入る
});
鍵のローテーション
認証プロバイダーは定期的に署名鍵をローテーションする。Cognito は自動的にローテーションを行い、JWKS エンドポイントには常に新旧両方の鍵が含まれる。
ローテーションの流れは以下の通りだ。
- 新しい鍵ペア (key-2) を生成し、JWKS に追加する
- 新しい JWT は key-2 で署名する
- 古い鍵 (key-1) で署名された JWT がまだ有効期限内なので、key-1 も JWKS に残す
- key-1 で署名された JWT が全て期限切れになったら、key-1 を JWKS から削除する
クライアント側の実装で重要なのは、JWKS をキャッシュしつつ、未知の kid に遭遇したら JWKS を再取得するロジックだ。キャッシュだけに頼ると、ローテーション直後に検証が失敗する。
API Gateway での JWT 検証
API Gateway (HTTP API) の JWT オーソライザーを使えば、Lambda 側で検証ロジックを実装する必要がない。
API Gateway が自動的に行う処理:
- JWKS エンドポイントから公開鍵を取得・キャッシュ
- JWT の署名検証
exp(有効期限) のチェックiss(発行者) とaud(対象者) の検証
Lambda には検証済みの claims がイベントオブジェクトに含まれて渡される。これにより、Lambda は認証ロジックを一切持たず、ビジネスロジックに集中できる。
RSA と EC の選択
JWK で使われる鍵の種類は主に RSA と EC (楕円曲線) の 2 つだ。
| 観点 | RSA (RS256) | EC (ES256) |
|---|---|---|
| 鍵サイズ | 2048 bit (256 bytes) | 256 bit (32 bytes) |
| 署名サイズ | 256 bytes | 64 bytes |
| 検証速度 | 速い | やや遅い |
| 署名速度 | 遅い | 速い |
| 互換性 | ほぼ全てのライブラリが対応 | 一部の古いライブラリで非対応 |
Cognito や Auth0 はデフォルトで RSA を使用する。JWT のサイズを小さくしたい場合 (モバイルアプリなど帯域が限られる環境) は EC を検討する価値がある。
よくある誤解
「JWKS エンドポイントは秘密にすべき」
JWKS エンドポイントは公開鍵を配布するためのものであり、秘密にする必要はない。公開鍵は文字通り「公開」するための鍵だ。秘密にすべきなのは署名に使う秘密鍵であり、これは認証プロバイダーの内部に保持される。
「JWT を検証すれば認可も完了」
JWT の署名検証は認証 (このトークンは本物か) を確認するだけだ。認可 (このユーザーにこの操作を許可するか) は、JWT のペイロードに含まれる claims (roles, scopes) を基に、アプリケーション側で別途判断する必要がある。
体系的に学ぶなら関連書籍を参照してほしい。
この記事は役に立ちましたか?
関連用語
JWT
JSON Web Token の略で、署名付きの JSON でユーザー情報を安全に伝達するトークン形式
OAuth 2.0
ユーザーのパスワードを渡さずに、リソースへの限定的なアクセスを許可する認可フレームワーク
Amazon Cognito
Web・モバイルアプリに認証・認可機能を追加する AWS マネージドサービス
ゼロトラスト
ネットワークの内外を問わず全てのアクセスを検証し、暗黙の信頼を排除するセキュリティモデル
SAML
企業の ID プロバイダーとサービスプロバイダー間でシングルサインオンを実現する XML ベースの認証プロトコル
API ファーストデザイン
実装の前に API の仕様を設計・合意し、フロントエンドとバックエンドの並行開発を可能にするアプローチ
関連する記事
深夜 3 時のデプロイ前に読み返したい 1 ページ
本番デプロイの直前、最終確認のチェックリストとして技術書の特定のページが役立つことがあります。緊張の場面で頼りになる「お守りの 1 ページ」の見つけ方と活用法。
技術書の読む順番戦略 - 複数冊を組み合わせて理解を加速させる
技術書を 1 冊ずつ読むのではなく、複数冊を戦略的に組み合わせることで理解の深さと速度を飛躍的に高める方法を解説します。
OS・低レイヤー本ガイド - コンピュータの仕組みを学ぶ技術書の選び方
OS、コンパイラ、ネットワークなど低レイヤーを学べる技術書の 4 ジャンルと、どこから始めるべきかの指針、賞味期限の見極め方を紹介します。