解碼和驗證來自 Google 的 Base64urlUInt 編碼的 RS256 公鑰
根據 Google 的說法,要訪問它與訪問令牌(用於訪問其 API)一起發送的 id_token,您必須首先使用此頁面提供的 RS256 公鑰驗證令牌。公鑰響應如下所示:
{ "kty": "RSA", "alg": "RS256", "use": "sig", "kid": "8c9eb968f73744eaed421e48010142bce51a067f", "n": "uweJ3hFY9wqZ6ZG-iSNhQwHtKCGl8G_jcQgGPjOrS-Rum3dyDjicqkAyfS8XDn480KD_TZ5m-lqBjqfimePu2_cH4URDPIwsqSzJI2_piEhaqnXRptIe5YB5imAL6iETKaOPjw284Fc7EdHK-ekHMn3AXjsy9AIErwAVw4-4ZXXwHbyQXJy1DyUB4ZzxiEvw_qkQmLdltmrNkLOw-Xh-C9UkTZ9NA58bYPBnxLwnAu_ggw_g_-hCAs6OvXZbAfFHhIGBLyjtdDLVrfXo1112QREB9d5sEds0bKZtJcD9afl4E7Ht6G-g3jNP2clAu6-6B-cIe4-j8Ph1uJDPkAmDfw", "e": "AQAB" },
根據 Google & RFC Specification 7518,這是一個 Base64urlUInt 編碼的 RS256 公鑰。“n”參數是模數,“e”參數是指數。其餘的只是用於驗證算法本身,與使用公鑰進行解密/驗證無關。
我的問題源於這樣一個事實,根據我在網上閱讀的內容,這不是標準的 RS256 公鑰。當試圖驗證我的 IDtoken 時,它會吐回來
ValueError: Could not deserialize key data.
(技術並不重要,但我在 python 中使用了 pyJWT 模組)。我知道問題不在於 ID 令牌,因為如果我跳過驗證,我就沒有問題。這當然不適合生產環境。我嘗試通過分別用 ‘+’ 和 ‘/’ 替換 ‘-’ 和 ‘_’ 以及添加 ‘=’ 進行填充來將其轉換為正常 Base64。我什至嘗試在 ‘—–BEGIN PUBLIC KEY—–\n’ 字元串前加上前綴並在末尾附加類似的字元串,但無濟於事。我還嘗試將“AQAB”指數附加到模數的末尾,但同樣沒有成功。
我也嘗試過使用其他線上生成的公鑰,並且工作正常。即使我故意打錯了它們,我也會收到一個錯誤,指出它根本無法驗證令牌,而不是吐出一個奇怪的
ValueError
.所以我的問題是存在的;Google 給我的“公鑰”模數/指數是否有問題,或者我如何使用/轉換它?我缺少步驟嗎?非常感謝任何幫助,因為我是這個主題的新手。提前致謝!!
這兩個值都是無符號的大端值,編碼為 base-64-url。基本上這意味著沒有符號位,並且最高有效位一直在左側(位 B_7 - 基於零的索引 - 在字節索引零上)。因此,您首先需要對這些值進行 base-64-url 解碼,然後將它們轉換為一個大數字。最後,您需要通過將數字提供為模數來組合兩個大數字以形成公鑰 $ n $ 和指數 $ e $ .
如果您無法將數字組合成公鑰,您可能需要將公鑰編碼為 PKCS#1 公鑰或
SubjectPublicKeyInfo
,這是一個 X.509 結構。對於這兩個操作,您要麼需要自己創建編碼(這非常困難),要麼需要訪問並了解如何使用 ASN.1 庫。您可能想看看“hazmat”密碼學包中的 RSA 公鑰介面,with
load_rsa_public_numbers
和public_bytes(encoding, format)
withPEM
andSubjectPublicKeyInfo
。