目錄

簡介 JWK 與 JWA

JWKJWA 定義了 JWSJWE 所能使用的演算法,以及金鑰(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全名說明
kidKey ID作為識別金鑰的識別碼,在多個金鑰保存的儲存空間裡,它必須要是唯一的
ktyKey TypeRSAECoct 三種
algAlgorithm這裡會對應到 JWA 所定義好的演算法
usePublic Key Usesig 指的是數位簽章、enc 則指的是加密
nModulusRSA 公鑰的模數值,它的內容會是 Base64urlUInt 編碼後的結果
eExponentRSA 公鑰的指數值,它的內容會是 Base64urlUInt 編碼後的結果

Blinding Operation 可參考維基百科,主要是為了防止 time attack。

Base64urlUInt 下面會說明。

由上例可了解,JWK 是一個使用 JSON 表示金鑰的方法,裡面也能帶有金鑰的 metadata,整包做序列化傳輸或是儲存都很方便。

JWA 預定義演算法有分三個 section,分別是:

  1. Section 3.1 定義 JWS 可以用的 alg
  2. Section 4.1 定義 JWE 可以用的 alg
  3. Section 5.1 定義 JWE 可以用的 enc

而個別 section 還有額外定義個別演算法的細節,和註冊 JWK 的參數(如 ECDH 註冊了 epk 等),詳細定義可以參考 IANA - JSON Object Signing and Encryption (JOSE)

JWK 有拿 Google 的 RSA 公鑰來介紹 JWK 的幾個必要參數,而 JWA 裡面也有定義 RSA 私錀還有哪些參數:

Parameter全名說明
dPrivate Exponent私有指數值
pFirst Prime Factor第一個質數
qSecond Prime Factor第二個質數
dpFirst Factor CRT Exponent第一個因數,指 d mod (p - 1)
dqSecond Factor CRT Exponent第二個因數,指 d mod (q - 1)
qiFirst CRT CoefficientCRT 係數,指 q^-1 mod p
othOther Primes Info質數的其他資訊

因 RSA 本質就是在算數學,所以上面所有參數都是 Base64urlUInt 編碼。

Base64urlUInt 在 JWA 有定義它的編碼方法,但說明有點難理解,我們直接把 AQAB 轉回位元試試,首先先查表

  • A = 000000
  • Q = 010000
  • B = 000001

AQAB = 000000 010000 000000 000001,轉換成數字即為 65537。若是最低位元的話,如 0 則會轉成 AA

JWK 與 JWA 有這些實例介紹,相信就會了解 JSON 結構以及如何在 RFC 上查詢對應的資料。

實際使用上,如 JWK 或 JWE 的 JOSE Header 就有一個欄位可以直接放 JWK 的內容或 URI,又或是像剛剛 Google 的範例可以直接下載 JWK 等。之後在介紹身分驗證時,就會需要使用到 JWK 了。