簡介 JWK 與 JWA

JWKJWA 定義了 JWSJWE 所能使用的演算法,以及金鑰(key)的格式。

簡介 JWK

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 RSAECoct 三種
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

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 全名 說明
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

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 了。

參考資料