目錄

簡介 JWS

JWS 的全名為 JSON Web Signature,定義在 RFC 7515 裡面,主要定義了資訊的格式以及序列化(serialization)的方法。從名字可以看得出,它有使用到數位簽章技術,或是它也可以使用訊息驗證碼來確保資料的來源以及完整性。

JWS 包含了三組內容:

  • JOSE Header
  • JWS Payload
  • JWS Signature

JOSE Header 裡則是由下列兩種 Header 聯集而成

  • JWS Protected Header
  • JWS Unprotected Header

JWS Payload 一般會存放 claim。JWS Signature 則是依演算法對 JWS Protected Header 與 JWS Payload 做簽章後,再編碼的內容。如果演算法為 none 的話,則 JWS Signature 會是一個空字串。

而序列化的方法有兩種:

  • JWS Compact Serialization
  • JWS JSON Serialization

JWS 需要了解的主要是 JOSE Header 的定義、序列化的方式、以及如何驗證簽章。

與 claim 類似,JOSE Header 也分為三類:

  1. Registered Header Parameter,RFC 裡預定義的 Header
  2. Public Header Parameter,在 IANA - JSON Object Signing and Encryption (JOSE) 公開註冊表上的 Header
  3. Private Header Parameter,除了上面兩種以外的 Header,通常是產生 JWS 與使用 JWS 雙方私下的協議,但不建議使用

而在 section 4.1 有列出預定義的 JOSE Header 有哪些,以下是比較常見的:

HeaderFull name中文
algAlgorithm簽章演算法,比方說 RS256
jkuJWK Set URL一個可以拿到 JWK Set 的 URL
jwkJSON Web Key一個代表 JWK 的 JSON 資料
kidKey ID如果有多個 JWK,則此 kid 應該會與某個 JWK 的 kid 相同
typType這個 token 的格式,一般會設定成 JWT
ctyContent type一般不會設定,但如果 payload 裡面是另一個 JWT 時,這裡可以設定成 JWT
critCritical值為一個陣列,內容為 Header Name,主要目的是讓接受者檢查關鍵的 Header 是否支援

對 X.509 不熟,且這次鐵人賽應該沒時間研讀,所以相關的資訊會先跳過。

而 JWS Protected Header 與 JWS Unprotected Header 的差別為:

Header Type完整性保護序列化支援
JWS Protected HeaderJWS Compact Serialization / JWS JSON Serialization
JWS Unprotected HeaderJWS JSON Serialization

傳輸資料時,通常都會做序列化。方法有兩種,一種是精簡格式 JWS Compact Serialization ,也就是類似 xxx.yyy.zzz 這個樣子:

BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload) || '.' || BASE64URL(JWS Signature)

另一種則是 JWS JSON Serialization,內容只有 JSON encode,裡面又分 GeneralFlattened 兩種格式。

General 大概長的像下面這樣

{
    "payload": "<payload contents>",
    "signatures": [
        {
            "protected": "<integrity-protected header 1 contents>",
            "header": "<non-integrity-protected header 1 contents>",
            "signature": "<signature 1 contents>"
        },
        {
            "protected": "<integrity-protected header n contents>",
            "header": "<non-integrity-protected header n contents>",
            "signature": "<signature n contents>"
        }
    ]
}

Flattened 則有點像 Compact 的 JSON 版:

{
    "payload": "<payload contents>",
    "protected": "<integrity-protected header contents>",
    "header": "<non-integrity-protected header contents>",
    "signature": "<signature contents>"
}

從上面的格式也可以發現,JWS 是有支援放多個簽章的。但只有 General JWS JSON Serialization 支援。

下面是一個簡單的序列化比較表:

Serialization支援 JWS Unprotected Header多個簽章URL 安全大小
JWS Compact SerializationNoNoYes
General JWS JSON SerializationYesYesNo
Flattened JWS JSON SerializationYesNoNo

從這個比較表可以知道 General 資訊比 Flattened 或 Compact 都來得完整,但就會大很多;而使用 JSON Serialization 時,會有編碼上的問題,所以 HTTP 傳輸通常還是 Compact 比較常見。