Public-Key

如何使用公鑰驗證使用私鑰生成的 JWT 簽名?

  • January 21, 2021

據我了解,JSON Web 令牌 (JWT)由 3 個部分組成:

  • 標頭,指定用於簽名的散列算法;
  • 有效載荷本身;和
  • 簽名,它是使用指定散列算法和給定秘密的標頭和有效負載的散列。

簽名的目的是讓接收者驗證接收到的 JWT 的完整性,即它沒有被篡改。這大概是通過 JWT 的接收者複製 JWT 生產者創建簽名的步驟來完成的,通過使用指定的散列算法和給定的秘密對標頭和有效負載進行散列。

當 JWT 發送方和接收方使用的密鑰相同(共享密鑰、對稱密鑰)時,我明白這是如何工作的。所有輸入都是相同的,因此無論是由發送方還是接收方計算,雜湊都是相同的。

我的實際問題和我不明白的是,當發送者和接收者使用的秘密不同(非對稱密鑰、公鑰/私鑰對)時,這是如何工作的。即,如果發送方產生的散列是使用密鑰生成的,而接收方產生的散列(用於簽名驗證目的)是由相應的公鑰產生的。

兩個不同的秘密如何產生相同的雜湊?

我從一個單獨的來源收到了以下解釋。

Send:    { object | encrypt(hash(object), private_key) }
Receive: { object | signature }
Verify:  hash(object) == decrypt(signature, public_key)

這解釋了我一直在努力理解的東西。

這裡有兩個過程在起作用:不僅是散列,還有加密。實際的散列本身不需要secret參數,它只接受要散列的對象(在 JWT 的情況下,標頭 + 有效負載的串聯)。生成的散列本身然後是加密的輸入,其結果形成簽名,然後可以由接收者解密以檢索原始散列以與接收者自己計算的散列進行比較。

因此,發送者和接收者無需使用不同的秘密執行類似的計算,以得到相同的雜湊值:

hash(object, private_key) == signature == hash(object, public_key)

我們寧願讓發送者和接收者執行互補計算以返回原始輸入

decrypt(encrypt(hash_value, private_key), public_key) == hash_value

這對我理解公私鑰加密的方式是有道理的。

引用自:https://crypto.stackexchange.com/questions/60703