SubtleCrypto.deriveBits()
Baseline Widely available *
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2020年1月.
* Some parts of this feature may have varying levels of support.
SubtleCrypto
接口的 deriveBits()
方法用于从一个基本密钥派生比特序列(数组)。
它以基本密钥、使用的派生算法和需要派生的比特长度为参数。返回一个 Promise
,会兑现一个包含派生比特序列的 ArrayBuffer
。
此方法与 SubtleCrypto.deriveKey()
非常类似,区别在于 deriveKey()
返回的是 CryptoKey
对象,而不是 ArrayBuffer
。本质上,deriveKey()
是由 deriveBits()
和 importKey()
这两个方法组合而成的。
该函数支持的派生算法与 deriveKey()
相同:ECDH、HKDF 和 PBKDF2。参见支持的算法以了解这些算法的详细信息。
语法
deriveBits(algorithm, baseKey, length)
参数
algorithm
-
一个对象,用于定义使用的派生算法。
- 使用 ECDH,则传入
EcdhKeyDeriveParams
对象。 - 使用 HKDF,则传入
HkdfParams
对象。 - 使用 PBKDF2,则传入
Pbkdf2Params
对象。
- 使用 ECDH,则传入
baseKey
-
一个
CryptoKey
,表示派生算法的输入。如果算法(algorithm
)是 ECDH,则该对象为 ECDH 的私钥。否则,它为派生函数的初始密钥材料(key material):例如,对于 PBKDF2,它可能是一个密码(使用SubtleCrypto.importKey()
导入为一个CryptoKey
对象)。 length
-
一个数字,表示要派生的比特位数。为了兼容所有浏览器,此数字应为 8 的倍数。
返回值
一个 Promise
,会兑现一个包含派生的比特序列的 ArrayBuffer
。
异常
当发生一下几种异常时,promise 会被拒绝:
OperationError
DOMException
-
若
deriveBits()
的 length 参数为 null,或在某些情况下如果 length 参数不是 8 的倍数,则会抛出此异常。 InvalidAccessError
DOMException
-
若基本密钥不是要求的派生算法的密钥,或
CryptoKey.usages
的值不包含deriveBits
,则会抛出此异常。 NotSupported
DOMException
-
若尝试使用未知或不适用于派生的算法,则会抛出此异常。
支持的算法
示例
备注: 你可以在 GitHub 上尝试可用的示例。
ECDH
在此示例中,Alice 和 Bob 分别生成了一个 ECDH 密钥对。
然后,我们使用 Alice 的私钥和 Bob 的公钥来派生一个共享密钥(shared secret)。在 GitHub 上查看完整代码。
async function deriveSharedSecret(privateKey, publicKey) { const sharedSecret = await window.crypto.subtle.deriveBits( { name: "ECDH", namedCurve: "P-384", public: publicKey, }, privateKey, 128, ); const buffer = new Uint8Array(sharedSecret, 0, 5); const sharedSecretValue = document.querySelector(".ecdh .derived-bits-value"); sharedSecretValue.classList.add("fade-in"); sharedSecretValue.addEventListener("animationend", () => { sharedSecretValue.classList.remove("fade-in"); }); sharedSecretValue.textContent = `${buffer}…[共 ${sharedSecret.byteLength} 字节]`; } // 生成两个 ECDH 密钥对:一个是 Alice 的,一个是 Bob 的 // 在正常的使用情况下,他们会单独生成密钥对,并安全地交换公钥。 const generateAlicesKeyPair = window.crypto.subtle.generateKey( { name: "ECDH", namedCurve: "P-384", }, false, ["deriveBits"], ); const generateBobsKeyPair = window.crypto.subtle.generateKey( { name: "ECDH", namedCurve: "P-384", }, false, ["deriveBits"], ); Promise.all([generateAlicesKeyPair, generateBobsKeyPair]).then((values) => { const alicesKeyPair = values[0]; const bobsKeyPair = values[1]; const deriveBitsButton = document.querySelector(".ecdh .derive-bits-button"); deriveBitsButton.addEventListener("click", () => { // 然后 Alice 使用她的私钥和 Bob 的公钥生成一个密钥(secret)。 // Bob 可以使用他的私钥和 Alice 的公钥来生成相同的密钥。 deriveSharedSecret(alicesKeyPair.privateKey, bobsKeyPair.publicKey); }); });
PBKDF2
在此示例中,我们要求用户提供密码,然后使用 PBKDF2 派生比特序列。在 GitHub 上查看完整代码。
let salt; /* 获取用于作为 deriveBits 方法的输入的密钥材料。 密钥材料是用户提供的密码。 */ function getKeyMaterial() { const password = window.prompt("请输入你的密码"); const enc = new TextEncoder(); return window.crypto.subtle.importKey( "raw", enc.encode(password), { name: "PBKDF2" }, false, ["deriveBits", "deriveKey"], ); } /* 通过用户提供的密码派生比特序列。 */ async function getDerivedBits() { const keyMaterial = await getKeyMaterial(); salt = window.crypto.getRandomValues(new Uint8Array(16)); const derivedBits = await window.crypto.subtle.deriveBits( { name: "PBKDF2", salt, iterations: 100000, hash: "SHA-256", }, keyMaterial, 256, ); const buffer = new Uint8Array(derivedBits, 0, 5); const derivedBitsValue = document.querySelector( ".pbkdf2 .derived-bits-value", ); derivedBitsValue.classList.add("fade-in"); derivedBitsValue.addEventListener("animationend", () => { derivedBitsValue.classList.remove("fade-in"); }); derivedBitsValue.textContent = `${buffer}…[共 ${derivedBits.byteLength} 字节]`; } const deriveBitsButton = document.querySelector(".pbkdf2 .derive-bits-button"); deriveBitsButton.addEventListener("click", () => { getDerivedBits(); });
规范
Specification |
---|
Web Cryptography Level 2> # SubtleCrypto-method-deriveBits> |
浏览器兼容性
Loading…