使用 WebCrypto derivedKey() API 生成 HMAC(SHA256) 密鑰
我正在使用 javascript WebCrypto API
window.crypto.subtle.deriveKey()
API 來生成這樣的 HMAC 密鑰:this.key = await window.crypto.subtle.deriveKey( { name: "PBKDF2", salt: someSalt, iterations: 50000, hash: "SHA-1" }, keyMaterial, // default length value! { name: "HMAC", hash:"SHA-256"}, true, [ "sign", "verify" ] );
現在,這裡是 MDN 網站 https://developer.mozilla.org/en-US/docs/Web/API/HmacKeyGenParams上的文件 提到的密鑰長度:
HmacKeyGenParams The HmacKeyGenParams dictionary of the Web Crypto API represents the object that should be passed as the algorithm parameter into SubtleCrypto.generateKey(), when generating a key for the HMAC algorithm. Properties name A DOMString. This should be set to HMAC. hash A DOMString representing the name of the digest function to use. You can pass any of SHA-1, SHA-256, SHA-384, or SHA-512 here. length Optional A Number — the length in bits of the key. If this is omitted the length of the key is equal to the length of the digest generated by the digest function you have chosen. Unless you have a good reason to use a different length, omit this property and use the default.
它基本上說密鑰的預設長度是摘要的長度(以位為單位)。假設 SHA256 的摘要大小(以位為單位)為 256,我期望密鑰長度等於 256 位。但是,將返回的對象轉儲到開發人員控制台中會顯示512
deriveKey()
位的長度(對於 chrome 和 firefox - 非常新的版本) . 撇開這類問題很難發現和調試(因為最初您看到在其他地方計算的某些消息摘要與在瀏覽器中計算的消息摘要不匹配),在修復問題之後(通過使用 256 位的顯式長度)有些事情我還是不明白:
- 哪個標準推薦了基於 HMAC 的簽名、身份驗證的密鑰長度?
- WebCrypto API 文件或其實現中是否存在錯誤?
- 哪個是基於 HMAC(SHA256) 的簽名的最佳/推薦密鑰長度?
deriveKey()
在 MDN 網站上記錄在這裡: https ://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey
- NIST SP 800-107,第 5.3.4 節,內容如下
讓 C 表示內部散列值的位長,在 FIPS 180-4 中用 H 表示。(在 Merkle-Damgård 風格的散列函式的描述中,這個 H 通常被稱為“連結值”。)請注意,C 並不(必然)等於 L,即散列函式輸出的位長度(例如,參見 SHA -384 或 SHA-512/t 對於任何 t < 512,其中 L < 512 = C)。在所有目前批准的雜湊函式中,L ≤ C(對於 SHA-1、SHA-256 和 SHA-512,L = C)。
HMAC密鑰的有效安全強度是K的安全強度和2C的值中的最小值。即,安全強度= min(K的安全強度,2C)。
- 看起來 API 旨在根據 NIST 文件生成具有 512 位安全強度的 HMACS,儘管 API 註釋似乎也沒有反映這一點。我假設其意圖是遵循 NIST 並且文件有問題。
- 在 NIST 發布之後,需要一個統一的隨機 512 位密鑰才能充分利用 SHA-256 算法提供的全部安全性。