JWK 與 JWA 定義了 JWS 與 JWE 所能使用的演算法,以及金鑰(key)的格式。
JWK 直接以 Google OAuth 2.0 所開放下載的 JWK 的其中一把 kid=8c58e138614bd58742172bd5080d197d2b2dd2f3
為實例:
{
"kid": "8c58e138614bd58742172bd5080d197d2b2dd2f3",
"kty": "RSA",
"alg": "RS256",
"use": "sig",
"n": "yf3ymX8X1Q-vGALjH5eW56DQY2eJMoVzIn35IsxqSRpDEdoC-mp7EmC63feBp_1uRR9ITCwliuNYAV1yOmpSOstGDRknhp5mzmc_EovqDH4jwI_TWmsDMDZ7rHTKq5DFKzAVJlkk85OLbbt1PU1ZCF2eYtCzb57STrhvhmuAPgmoqROmNUKF5BcBQw7pvKqV2CjJRdKUmxs_zW9qNUYyDZaPYMfiloGjytsFsPp-lyQyxbXJoUbUD7jA6cUb3mOtzpROAgkYZyS740g-GZcVLapqAwC6UZxlCN-lXbGab7c-QrCMvDwfu2U3AQSvI38u95MabrjHZWsWRCbqJVfHIw",
"e": "AQAB",
}
以這裡的參數為例:
Parameter | 全名 | 說明 |
---|---|---|
kid | Key ID | 作為識別金鑰的識別碼,在多個金鑰保存的儲存空間裡,它必須要是唯一的 |
kty | Key Type | 有 RSA 、EC 、oct 三種 |
alg | Algorithm | 這裡會對應到 JWA 所定義好的演算法 |
use | Public Key Use | sig 指的是數位簽章、enc 則指的是加密 |
n | Modulus | RSA 公鑰的模數值,它的內容會是 Base64urlUInt 編碼後的結果 |
e | Exponent | RSA 公鑰的指數值,它的內容會是 Base64urlUInt 編碼後的結果 |
Blinding Operation 可參考維基百科,主要是為了防止 time attack。
Base64urlUInt 下面會說明。
由上例可了解,JWK 是一個使用 JSON 表示金鑰的方法,裡面也能帶有金鑰的 metadata,整包做序列化傳輸或是儲存都很方便。
JWA 預定義演算法有分三個 section,分別是:
alg
alg
enc
而個別 section 還有額外定義個別演算法的細節,和註冊 JWK 的參數(如 ECDH 註冊了 epk
等),詳細定義可以參考 IANA - JSON Object Signing and Encryption (JOSE)。
JWK 有拿 Google 的 RSA 公鑰來介紹 JWK 的幾個必要參數,而 JWA 裡面也有定義 RSA 私錀還有哪些參數:
Parameter | 全名 | 說明 |
---|---|---|
d | Private Exponent | 私有指數值 |
p | First Prime Factor | 第一個質數 |
q | Second Prime Factor | 第二個質數 |
dp | First Factor CRT Exponent | 第一個因數,指 d mod (p - 1) |
dq | Second Factor CRT Exponent | 第二個因數,指 d mod (q - 1) |
qi | First CRT Coefficient | CRT 係數,指 q^-1 mod p |
oth | Other Primes Info | 質數的其他資訊 |
因 RSA 本質就是在算數學,所以上面所有參數都是 Base64urlUInt 編碼。
Base64urlUInt 在 JWA 有定義它的編碼方法,但說明有點難理解,我們直接把 AQAB
轉回位元試試,首先先查表:
AQAB = 000000 010000 000000 000001
,轉換成數字即為 65537。若是最低位元的話,如 0 則會轉成 AA
。
JWK 與 JWA 有這些實例介紹,相信就會了解 JSON 結構以及如何在 RFC 上查詢對應的資料。
實際使用上,如 JWK 或 JWE 的 JOSE Header 就有一個欄位可以直接放 JWK 的內容或 URI,又或是像剛剛 Google 的範例可以直接下載 JWK 等。之後在介紹身分驗證時,就會需要使用到 JWK 了。