如果你有使用 JWT、OAuth,或其他基於 Token 的驗證機制,應該對 JWKS 不陌生。那麼,JWKS 到底是什麼?為什麼重要?
簡單來說,JWKS(JSON Web Key Set) 是一個標準化的 JSON 文件,用來公開一組以上的公開金鑰(JWKs),讓客戶端與 API 可以用來驗證簽章或進行加密。
這份指南會用淺顯的方式解釋 JWKS,展示 JWK 的格式與範例,說明 jwks_uri 的用途,並提供在生產環境建立與管理 JWKS 的實務建議。
認識 JWK 與 JWKS
- JWK(JSON Web Key)
JWK 是一個 JSON 物件,用來表示一把密鑰,例如 RSA 公鑰或 EC 金鑰。常見欄位包括: -kty(金鑰類型)
-kid(金鑰 ID)
-use(用途,例如sig簽章驗證、enc加密)
-alg(演算法)
- 金鑰內容(例如 RSA 的n/e,或 EC 的x/y) - JWKS(JSON Web Key Set)
JWKS 則是包含多個 JWK 的 JSON 文件。例如:
{
"keys": [
{
"kty": "RSA",
"kid": "2023-01-key-1",
"use": "sig",
"alg": "RS256",
"n": "...",
"e": "AQAB"
}
]
}
因為 Token 的發行服務會公開 JWKS,其他服務(API、客戶端)就能自動抓取這些公開金鑰來驗證簽章或進行加密。JWKS 的標準化設計,讓各種程式庫都能互通。
JWKS 在驗證與 API 架構中的角色
在 API 生態系中,典型流程如下:
- 發行方(Issuer):在固定網址(
jwks_uri)公開 JWKS。 - 客戶端或資源伺服器:抓取 JWKS 並快取。
- 驗證 Token:當收到 JWT 時,Token header 的
kid會指出要用哪一把 key。 - 比對金鑰:客戶端從 JWKS 找到對應 JWK,並用它驗證簽章或進行加密相關處理。
- 金鑰輪替(Key Rotation):只要更新 JWKS,客戶端就能自動使用新的公開金鑰,不需要重新部署程式。
如果是 JWE(加密 Token),JWKS 也可以提供加密用的公開金鑰。
jwks_uri:如何找到與使用
許多身分驗證服務(例如 OpenID Connect)會在 Discovery 文件中提供 jwks_uri,通常位於 /.well-known/openid-configuration,例如:
{
"issuer": "https://idp.example.com",
"jwks_uri": "https://idp.example.com/.well-known/jwks.json"
}
使用方式:
- 在 OIDC/OAuth 客戶端函式庫中設定
jwks_uri,或讀取 Discovery 文件自動取得。 - 函式庫會抓取並快取 JWKS,並透過
kid找到正確的 JWK。 - 建立快取更新策略(例如定期刷新,或驗證失敗時重新抓取)。
- 建議:一定要透過 HTTPS 提供 JWKS,並使用穩定的
kid方便輪替。
JWK 格式範例與欄位解說
以下是一個 RSA 公鑰 JWK:
{
"kty": "RSA",
"kid": "2011-04-29",
"use": "sig",
"alg": "RS256",
"n": "oahUI...base64url-modulus...",
"e": "AQAB"
}
欄位說明:
kty— 金鑰類型(RSA、EC、oct)kid— 金鑰 ID,用來在 JWKS 中選擇正確的金鑰use— 用途:sig簽章驗證、enc加密alg— 演算法,例如RS256、ES256n, e(RSA)或x, y, crv(EC)— 公鑰內容,使用 base64url 編碼
完整 JWKS 範例(含 RSA 與 EC 金鑰):
{
"keys":[
{"kty":"RSA","kid":"rsa1","use":"sig","alg":"RS256","n":"...","e":"AQAB"},
{"kty":"EC","kid":"ec1","use":"enc","alg":"ECDH-ES","crv":"P-256","x":"...","y":"..."}
]
}
PEM 與 JWK 的轉換
PEM(Privacy-Enhanced Mail)是常見的金鑰與憑證格式,以 Base64 編碼的 DER,加上標頭與標尾,例如:
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
你可能會遇到需要將 PEM 格式的公鑰轉換成 JWK:
- 產生 RSA 公鑰 PEM:
openssl rsa -in private.pem -pubout -out public.pem
- 產生 EC 公鑰 PEM:
openssl ec -in key.pem -pubout -out public.pem
再用 JOSE 類庫(如 node-jose、python-jose)或工具把 PEM 公鑰轉換成 JWK。
如果需要快速操作,可以使用 Authgear JWK Generator,將 PEM 公鑰轉換為正確格式的 JWK,方便直接加入 JWKS。
⚠️ 安全提醒:
- 絕對不要在 JWKS 中公開私鑰
- JWKS 必須透過 HTTPS 提供
- 制定安全的金鑰輪替策略
建立與管理 JWKS 的最佳實踐
建立 / 發佈
- 使用函式庫或工具(node-jose、python-jose、OpenSSL + 轉換器)產生 JWK
- JWKS 中僅包含公開金鑰
- 放置於穩定的 HTTPS endpoint(例如
/.well-known/jwks.json) - 每把金鑰設定
kid,方便未來輪替
金鑰輪替(Key Rotation)流程
- 產生新金鑰對,將公開金鑰加入 JWKS,設定新
kid - 伺服器改用新的私鑰簽章 Token
- 保留舊金鑰於 JWKS,直到舊 Token 全部過期
- 移除舊金鑰
安全最佳實踐
- 僅透過 HTTPS 提供 JWKS
- JWKS 可快取,但在驗證失敗時必須能刷新
- JWKS 應只包含目前使用中的金鑰
- 監控驗證失敗日誌,偵測金鑰缺失或
kid不匹配
常見問題(FAQ)
Q: JWKS 有什麼用途?
A: 用來公開一組公開金鑰,讓客戶端或 API 抓取,用於 JWT 簽章驗證或加密。
Q: JWKS 檔案是公開的嗎?
A: 是的,JWKS 通常僅包含公開金鑰,私鑰必須妥善保護,不能公開。
Q: 要怎麼產生 JWK?
A: 可以透過 OpenSSL 轉換、JOSE 類庫,或直接使用 Authgear JWK Generator。
Q: JWKS 與 JWT / JWE 的關係?
- JWT(簽章 Token):JWT header 中的
kid會對應到 JWKS 裡的 JWK,用來驗證簽章。 - JWE(加密 Token):JWKS 可以公開加密用的公鑰,用於加密與解密流程。
結語
JWKS(JSON Web Key Set)雖然小巧,但在 Token 安全架構中至關重要。它標準化了「如何公開與取得公開金鑰」,讓服務之間能自動化、安全地進行簽章驗證與加密。
要點包括:
- 使用正確的 JWK 格式
- 透過 HTTPS 安全公開 JWKS
- 建立金鑰輪替策略
- 善用工具(如 Authgear JWK Generator)加快開發與測試
原文英文版刊於:What is JWKS? JSON Web Key Set Explained with Examples - Authgear Blog










