JWS 能保護資料的完整性,但資料傳輸過程是明碼傳輸,因此有心人士還是有辦法截取 JWS Payload 裡的內容做其他利用。如果內容也不希望被其他人看到的話,那還有另一個選擇就是 JWE--RFC 7516 - JSON Web Encryption。
相較於 JWS,JWE 的一切資訊都顯得複雜很多,如資訊的組成就有六組:
跟 JWS 一樣,也有 JOSE Header,但它是下面三種 Header 聯集而成,也比 JWS 複雜:
而序列化的方法跟 JWS 類似,分成兩種:
雖然比較複雜,但了解上面定義的這些方法,大概就可以了解 JWE 的結構為何了。
JOSE Header 跟 JWS 一樣有分三種類型,就不重覆說明了,註冊表也一樣可以查 IANA - JSON Object Signing and Encryption (JOSE) 公開註冊表。
而在 RFC 7516 section 4.1 定義的 Header 也與 JWS 大同小異,這裡補充多出來的:
Header | Full name | 中文 |
---|---|---|
enc |
Encryption Algorithm | 關聯數據認證加密演算法,如 A256GCM |
zip |
Compression Algorithm | 壓縮演算法,目前只有 DEF (DEFLATE)一種 |
關聯數據認證加密 參考維基百科說明,大概理解為結合[加密][Day 08]與[訊息驗證碼][Day 10]的功能,產生出帶有認證功能的密文。
因 JWE 有定義收件人(recipient)的屬性,所以會有 Per-Recipient 與 Shared 的差異。三種 Header 類型的差異如下:
Header Type | 完整性保護 | 收件人 | 序列化支援 |
---|---|---|---|
JWE Protected Header | 有 | 全部 | JWE Compact Serialization / JWE JSON Serialization |
JWE Shared Unprotected Header | 無 | 全部 | JWE JSON Serialization |
JWE Per-Recipient Unprotected Header | 無 | 單一 | JWE JSON Serialization |
資料結構上,除了跟 JWS 相同的 JOSE Header 以外,其他都是 JWE 特有的內容。
Section | 說明 |
---|---|
JWE Encrypted Key | 加密過後的密鑰,演算法不支援則會是空的 |
JWE Initialization Vector | 加密的時候使用的初始化向量,演算法不支援則會是空的 |
JWE AAD | 完整性保護的額外參數,只有在 JWE JSON Serialization 才能使用 |
JWE Ciphertext | 密文 |
JWE Authentication Tag | 身分驗證的標記,使用附加的身分驗證資料,對明文加密而來的 |
與 JWS 類似,分為 JWE Compact Serialization 與 JWE JSON Serialization 兩種。JWE Compact Serialization 比 JWS Compact Serialization 多了兩個參數。
BASE64URL(UTF8(JWE Protected Header)) || '.' ||
BASE64URL(JWE Encrypted Key) || '.' ||
BASE64URL(JWE Initialization Vector) || '.' ||
BASE64URL(JWE Ciphertext) || '.' ||
BASE64URL(JWE Authentication Tag)
而 JWE JSON Serialization 也是分為 General 與 Flattened 兩種格式。
General JWE JSON Serialization 官方範例如下:
{
"protected": "<integrity-protected shared header contents>",
"unprotected": "<non-integrity-protected shared header contents>",
"recipients": [
{
"header": "<per-recipient unprotected header 1 contents>",
"encrypted_key": "<encrypted key 1 contents>"
},
{
"header": "<per-recipient unprotected header N contents>",
"encrypted_key": "<encrypted key N contents>"
}
],
"aad": "<additional authenticated data contents>",
"iv": "<initialization vector contents>",
"ciphertext": "<ciphertext contents>",
"tag": "<authentication tag contents>"
}
Flattened JWE JSON Serialization 官方範例如下:
{
"protected": "<integrity-protected header contents>",
"unprotected": "<non-integrity-protected header contents>",
"header": "<more non-integrity-protected header contents>",
"encrypted_key": "<encrypted key contents>",
"aad": "<additional authenticated data contents>",
"iv": "<initialization vector contents>",
"ciphertext": "<ciphertext contents>",
"tag": "<authentication tag contents>"
}
從這兩個範例可以了解,先前有提到 JWE 定義的 recipients 參數,只能用在 General JWE JSON Serialization。
下面是一個簡單的序列化比較表,其實跟 JWS 差異不大:
Serialization | 支援 JWE AAD | 支援 JWE Shared Unprotected Header | 支援 JWE Per-Recipient Unprotected Header | URL 安全 | 大小 |
---|---|---|---|---|---|
JWE Compact Serialization | No | No | No | Yes | 小 |
General JWE JSON Serialization | Yes | Yes | Yes | No | 大 |
Flattened JWE JSON Serialization | Yes | Yes | No | No | 中 |
從這張表可以了解,沒有特別需求的話,還是 JWE Compact Serialization 比較適用。但如果有需要特殊的參數如 JWE AAD,甚至是 JWE Per-Recipient Unprotected Header 的話,則就得考慮 JWE JSON Serialization。
只是實務上,最常使用的還是 JWS + JWS Compact Serialization。