RS256 的簽名長度是否取決於用於簽名的 RSA 密鑰的大小?
以下 NodeJS 程式碼在執行 (v16.8.0) 時會記錄
512
到標準輸出。const crypto = require("crypto"); const { privateKey } = crypto.generateKeyPairSync("rsa", { modulusLength: 4096, }); const sign = crypto.createSign("RSA-SHA256").update("somestringtosign"); const signature = sign.sign(privateKey); console.log(signature.length); // logs 512
如果我將模數長度更改為
2048
,則256
記錄為標準輸出。我想這是有道理的,正如RSA 規範所說:
signature, an octet string of length k, where k is the length in octets of the RSA modulus n
. 因此,256 位雜湊 (SHA256) 在使用具有 4096 位模數的 RSA 密鑰簽名時,具有 4096 位(512 字節)輸出。RS256 中的簽名長度確實可以長於 256,這取決於使用的 RSA 密鑰的大小嗎?使用比使用的散列函式長的模數是否“奇怪”?我看到簽署 JWT 的各種身份提供者確實都使用 2048 位模數,但這可能是巧合。
(我注意到RS256 的 IETF 規範說:
A key of size 2048 bits or larger MUST be used with these algorithms.
所以顯然規範允許 4096 的模數)更新
感謝評論和答案,我現在明白我問了“錯誤”的問題。我(錯誤地)期望 JWT 簽名的長度等於散列算法(SHA256)產生的散列摘要的長度。我在其中混淆了位和字節,因為例如 SHA256 產生 256 位(不是字節)的摘要。我在我的案例中看到的簽名長度是 256 字節(不是位),我現在理解應該等於公鑰模數的長度(確實是這種情況,我稍後可以驗證)。
RS256 中的簽名長度確實可以長於 256,這取決於使用的 RSA 密鑰的大小嗎?
是的。在 RSA(包括 RS256,即RSASSA-PKCS1-v1_5與 SHA-256 作為雜湊)中,簽名大小取決於用於簽名的 RSA 密鑰(實際上是公共模數)的大小。具體來說,簽名大小(以字節為單位,在重新編碼為文本之前)是密鑰大小(以位為單位),除以 8 並四捨五入到下一個整數。 $ \lceil 2048/8\rceil=256 $ 字節。 $ \lceil 4096/8\rceil=512 $ 字節。
使用比使用的散列函式長的模數是否“奇怪”?
不,這甚至是必需的。從格式化的角度來看,RS256(帶有 SHA-256 的 RSASSA-PKCS1-v1_5)的最小簽名大小為 $ 2+8+1+19+32=62 $ 字節,即 489 位公共模數。不過,那太小了,不安全。2048 位被認為是新應用程序的基準。預計它將針對經典電腦提供 112 位到 128 位的安全性,與 224 位或 256 位雜湊的抗碰撞性相當。有關密鑰大小的建議,請參閱此內容,以及分解攻擊的狀態。
我不知道標准上限,而且我認為沒有理由不支持至少 2048 字節(16384 位)的簽名。