在前兩篇文章中,我們介紹了 JWT 的運作原理和組成結構。
你可能會好奇:JWT 的這些規則是誰定義的?Header 要放什麼、Signature 要怎麼算,這些標準從哪裡來?
答案是:JOSE。
JOSE 是什麼?
JOSE 的全名是 JSON Object Signing and Encryption,中文可以翻譯成「JSON 物件簽署與加密」。
它不是一個工具,而是一套規範。這套規範定義了:
- 如何對 JSON 資料產生「簽名」(防止資料被竄改)
- 如何對 JSON 資料進行「加密」(防止資料被看到)
- 該用什麼演算法
- 金鑰的格式該長什麼樣子
JWT 就是根據 JOSE 規範所設計出來的。
為什麼要有這套規範?
想像一下,如果沒有統一的規範:
- A 公司的 JWT 用一種格式
- B 公司的 JWT 用另一種格式
- 每個人的簽名算法都不一樣
這樣大家的系統就無法互通。
有了 JOSE 規範,所有人都用同樣的格式、同樣的命名方式,不同系統之間就能互相理解對方的 Token。
JOSE 的四大規範
JOSE 底下有四個子規範,各自負責不同的事情:
| 規範 | 全名 | 負責的事情 |
|---|---|---|
| JWA | JSON Web Algorithms | 定義可以用哪些演算法 |
| JWK | JSON Web Key | 定義金鑰的格式 |
| JWS | JSON Web Signature | 定義如何產生「簽名」來防止竄改 |
| JWE | JSON Web Encryption | 定義如何「加密」資料 |
flowchart TB
JOSE[JOSE 規範]
JOSE --> JWA[JWA<br/>演算法]
JOSE --> JWK[JWK<br/>金鑰格式]
JOSE --> JWS[JWS<br/>簽名]
JOSE --> JWE[JWE<br/>加密]
JWS --> JWT[JWT]
JWE --> JWT
接下來,我們逐一介紹這四個規範。
JWA(JSON Web Algorithms)
JWA 定義了「可以使用哪些演算法」。
在前一篇文章中,我們提到 JWT 的 Header 裡有一個 alg 欄位:
{
"alg": "HS256",
"typ": "JWT"
}
這個 HS256 是哪裡來的?就是 JWA 規範定義的。
JWA 定義的演算法
JWA 規範列出了所有「官方認可」的演算法,包括:
用於產生簽名(JWS)的演算法:
| 演算法 | 說明 |
|---|---|
| HS256、HS384、HS512 | HMAC 搭配 SHA-256/384/512 |
| RS256、RS384、RS512 | RSA 搭配 SHA-256/384/512 |
| ES256、ES384、ES512 | ECDSA 搭配 SHA-256/384/512 |
| PS256、PS384、PS512 | RSA-PSS 搭配 SHA-256/384/512 |
| none | 不產生簽名(不建議使用) |
用於加密(JWE)的演算法:
| 演算法 | 說明 |
|---|---|
| A128GCM、A256GCM | AES-GCM 加密 |
| A128CBC-HS256 | AES-CBC 搭配 HMAC |
| RSA-OAEP | RSA 加密 |
為什麼需要統一定義演算法?
如果沒有統一定義,可能會發生:
- 有人用了不安全的演算法,卻不知道
- 接收方不認識發送方用的演算法,無法驗證
- 不同系統對同一個演算法的命名不一致
JWA 規範解決了這些問題:它告訴大家「這些演算法是安全的、可以用的」,也統一了命名方式。
JWK(JSON Web Key)
JWK 定義了「金鑰該用什麼格式表示」。
在前一篇文章中,我們提到對稱式演算法用 Secret,非對稱式演算法用 Private Key 和 Public Key。但這些金鑰該怎麼儲存、怎麼傳遞?
JWK 規範定義了一種用 JSON 格式來表示金鑰的方式。
JWK 長什麼樣子?
一個對稱式金鑰(用於 HS256)的 JWK:
{
"kty": "oct",
"k": "AyM32w-Gm2h5V_TJ_FjYXXjLxGh2QlTcF8qTkL3FJ3k",
"alg": "HS256"
}
一個非對稱式公鑰(用於 RS256)的 JWK:
{
"kty": "RSA",
"n": "0vx7agoebGcQ...",
"e": "AQAB",
"alg": "RS256",
"use": "sig"
}
JWK 的常見欄位
| 欄位 | 說明 |
|---|---|
kty | Key Type,金鑰類型(RSA、EC、oct) |
use | 用途(sig 用於簽名、enc 用於加密) |
alg | 搭配的演算法 |
kid | Key ID,金鑰的識別碼 |
JWKS(JSON Web Key Set)
當你有多把金鑰時,可以把它們放在一起,這就是 JWKS:
{
"keys": [
{ "kty": "RSA", "kid": "key-1", ... },
{ "kty": "RSA", "kid": "key-2", ... }
]
}
很多服務會公開它們的 JWKS,讓其他人可以取得公鑰來驗證 JWT。例如 Google 的 JWKS 端點:
https://www.googleapis.com/oauth2/v3/certs
JWS(JSON Web Signature)
JWS 定義了「如何對資料產生簽名」。
這是重點:我們前兩篇文章介紹的 JWT,其實就是 JWS。
JWT 和 JWS 的關係
你可能會困惑:JWT 和 JWS 有什麼不同?
簡單來說:
- JWS 是「帶有簽名的 JSON 資料」的格式規範
- JWT 是 JWS 的一種「應用」,專門用來傳遞身份資訊
我們常說的 JWT(有三個部分,用 . 分隔),其實正式名稱是「使用 JWS Compact Serialization 格式的 JWT」。
eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxMjN9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV這個格式就是 JWS 定義的。
JWS 的結構
JWS 定義了 JWT 的三段式結構:
Base64Url(Header).Base64Url(Payload).Base64Url(Signature)以及 Signature 的計算方式:
Signature = 演算法(Base64Url(Header) + "." + Base64Url(Payload), 金鑰)這些在前兩篇文章都介紹過了,現在你知道它們的來源是 JWS 規範。
JWE(JSON Web Encryption)
JWE 定義了「如何對資料進行加密」。
在前一篇文章中,我們強調過:JWT 的 Payload 是 Base64 編碼,任何人都能解碼看到內容。
但如果你的資料真的需要保密呢?這時候就可以用 JWE。
JWS vs JWE
JWS 和 JWE 最大的差別在於:Payload 的處理方式不同。
| JWS | JWE | |
|---|---|---|
| Payload 的處理 | 編碼(Base64) | 加密 |
| 內容可見性 | 任何人都能解碼看到 | 只有有金鑰的人能解密看到 |
| 防竄改 | ✅ 有簽名驗證 | ✅ 有驗證機制 |
| 我們常用的 JWT | ✅ 是這個 |
簡單說:
- JWS:內容是「編碼」的,大家都能看,但改了會被發現
- JWE:內容是「加密」的,沒有金鑰的人看不到
JWE 的結構
JWE 的格式比 JWS 複雜,有五個部分:
Header.EncryptedKey.IV.Ciphertext.AuthTag| 部分 | 說明 |
|---|---|
| Header | 描述加密方式 |
| EncryptedKey | 加密過的內容加密金鑰 |
| IV | 初始化向量 |
| Ciphertext | 加密後的內容 |
| AuthTag | 驗證標籤 |
什麼時候用 JWE?
大多數情況下,我們用的都是 JWS(一般的 JWT)。因為:
- JWT 的 Payload 本來就不該放機密資訊
- 傳輸過程有 HTTPS 保護
- JWE 比較複雜,處理起來也比較慢
只有在特殊情況下才需要 JWE,例如:
- 需要在 JWT 中放一些敏感資訊
- Token 可能會經過不信任的中間人
JWT 的兩種形式
現在你知道了,JWT 其實可以有兩種形式:
| JWS 形式的 JWT | JWE 形式的 JWT | |
|---|---|---|
| 結構 | 三段(Header.Payload.Signature) | 五段(Header.EncryptedKey.IV.Ciphertext.AuthTag) |
| 內容 | 可以被解碼看到 | 加密過,看不到 |
| 常見程度 | 非常常見 | 較少見 |
我們平常說的「JWT」,99% 指的都是 JWS 形式。
這些規範的關係
讓我們整理一下這些規範之間的關係:
flowchart TB
subgraph JOSE[JOSE 規範家族]
JWA[JWA<br/>定義演算法]
JWK[JWK<br/>定義金鑰格式]
JWS[JWS<br/>定義簽名格式]
JWE[JWE<br/>定義加密方式]
end
JWA -->|演算法清單| JWS
JWA -->|演算法清單| JWE
JWK -->|金鑰格式| JWS
JWK -->|金鑰格式| JWE
JWS -->|帶簽名的 Token| JWT[JWT<br/>JSON Web Token]
JWE -->|加密過的 Token| JWT
- JWA 提供演算法清單給 JWS 和 JWE 使用
- JWK 提供金鑰格式給 JWS 和 JWE 使用
- JWS 和 JWE 是產生 JWT 的兩種方式
小結
現在你知道了:
- JOSE 是一套規範,定義了如何對 JSON 資料產生簽名和加密
- JWA 定義了可以使用哪些演算法(HS256、RS256 等)
- JWK 定義了金鑰的 JSON 格式
- JWS 定義了如何產生簽名,我們常用的 JWT 就是 JWS 格式
- JWE 定義了如何加密資料,用於需要保密的場景
- 平常說的「JWT」,幾乎都是指 JWS 形式的 JWT
這些規範你不需要背起來,只要知道它們的存在和大概的用途就好。當你看到 JWA、JWK、JWS、JWE 這些名詞時,不會一頭霧水就夠了。