我一直在使用 TIDAL 的 auth web sdk 开发一个应用程序。在其中,他们使用与
MDN 文档中示例中的参数几乎相同的参数调用 SubtleCrypto 的
wrapKey
函数。
const wrapCryptoKey = async ({
keyToWrap,
password,
salt
}) => {
const keyMaterial = await getKeyMaterial(password);
const wrappingKey = await getWrappingKey(keyMaterial, salt);
return globalThis.crypto.subtle.wrapKey(
"raw",
keyToWrap,
wrappingKey,
"AES-KW"
);
};
getWrappingKey
:
const getWrappingKey = (keyMaterial, salt) => {
return globalThis.crypto.subtle.deriveKey(
{
hash: "SHA-256",
iterations: 1e5,
name: "PBKDF2",
salt
},
keyMaterial,
{ length: 256, name: "AES-KW" },
true,
["wrapKey", "unwrapKey"]
);
};
但是,当运行时,它会抛出密码未知的错误。 AES-KW 被列为受我的节点版本支持 (
v20.14.0
)。我哪里错了?
at SubtleCrypto.wrapKey (node:internal/crypto/webcrypto:715:10) {
[cause]: Error: Unknown cipher
at node:internal/crypto/aes:145:27
at node:internal/crypto/util:430:19
at new Promise (<anonymous>)
at jobPromise (node:internal/crypto/util:428:10)
at asyncAesKwCipher (node:internal/crypto/aes:145:10)
at Object.aesCipher (node:internal/crypto/aes:212:27)
at cipherOrWrap (node:internal/crypto/webcrypto:918:12)
at SubtleCrypto.wrapKey (node:internal/crypto/webcrypto:715:10)
at async handleNewCryptoKey (../node_modules/@tidal-music/auth/dist/index.js:273:22)
at async Module.init (../node_modules/@tidal-music/auth/dist/index.js:479:32) {
code: 'ERR_CRYPTO_UNKNOWN_CIPHER'
}
}
我尝试更新到最新的节点版本并重新启动和重建我的项目,但无济于事。
这个问题是由于在
主电子进程中调用
wrapKey
引起的。 Electron 使用 BoringSSL(与使用 OpenSSL 的 Node.js 相反),它不支持 AES-KW 作为算法。
来自电子问题#41720:
Node.js 本身使用 OpenSSL 来支持加密,而 Electron 使用 BoringSSL:与 Node.js 相比,来自 Chromium 的 OpenSSL 分支显着减少。这里的实际错误是不支持该密码,这是 BoringSSL 故意做出的选择。然而,它是在 WebCrypto 中实现的,因此如果您愿意,您可以在渲染器进程中使用它。
正如引用中提到的,Electron 确实 使用 Node.js 在渲染器进程中支持加密。我通过创建一个临时浏览器窗口并将对 TIDAL api 的调用移入其中并通过
ipcRenderer
与主进程通信来解决了我的问题。