edge-runtime
edge-runtime copied to clipboard
crypto.subtle.importKey does not accept ArrayBuffer (ArrayBuffer.prototype mismatch)
Node.js 20.11.1 [email protected]
Bug Report
Current behavior
foo.js:
(async () => {
const key = new ArrayBuffer(8);
const data = new ArrayBuffer(8);
const importedKey = await crypto.subtle.importKey(
"raw",
key,
{
name: "HMAC",
hash: { name: "SHA-256" },
},
false,
["sign"],
);
await crypto.subtle.sign("HMAC", importedKey, data);
})();
cmd:
$ npm exec edge-runtime foo.js
result(error):
node:internal/crypto/webidl:45
const err = new TypeError(message);
^
TypeError: Failed to execute 'importKey' on 'SubtleCrypto': 2nd argument is not instance of ArrayBuffer, Buffer, TypedArray, or DataView.
at codedTypeError (node:internal/crypto/webidl:45:15)
at makeException (node:internal/crypto/webidl:54:10)
at converters.BufferSource (node:internal/crypto/webidl:221:11)
at SubtleCrypto.importKey (node:internal/crypto/webcrypto:589:36)
at evalmachine.<anonymous>:6:45
at evalmachine.<anonymous>:19:3
at Script.runInContext (node:vm:133:12)
at runInContext (node:vm:287:6)
at EdgeVM.evaluate (/dev/edge/node_modules/@edge-runtime/vm/dist/vm.js:26:38)
at new EdgeVM (/dev/edge/node_modules/@edge-runtime/vm/dist/edge-vm.js:49:18) {
code: 'ERR_INVALID_ARG_TYPE'
}
Node.js v20.11.1
Expected behavior/code
Done without error
Additional context/screenshots
The above code has been verified to work with raw Node.js, Firefox and Chrome.
ArrayBuffer.prototype seems to be different from the original. Node.js checks here: https://github.com/nodejs/node/blob/9b1bf44ea9e7785e38c93b7d22d32dbca262df6c/lib/internal/crypto/webidl.js#L183
return ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, V);
Wrapping with uint8array is a workaround:
(async () => {
const key = new ArrayBuffer(8);
const data = new ArrayBuffer(8);
const importedKey = await crypto.subtle.importKey(
"raw",
new Uint8Array(key),
{
name: "HMAC",
hash: { name: "SHA-256" },
},
false,
["sign"],
);
await crypto.subtle.sign("HMAC", importedKey, new Uint8Array(data));
})();