cloudworker
cloudworker copied to clipboard
use native nodejs webcrypto implementation
instead of one that depends on openssl
Thanks but it appears that this broke the hmac e2e gets
So this exposed a fundamental flaw with the way things are architected. The TLDR is that libraries used by worker scripts (e.g. anything loaded via the Context) can't used instanceof
because the libraries are required in one realm (the original process) but used in another realm (the VM within which the worker script gets executed). This new crypto library uses instanceof
and breaks because of that. Adding ArrayBuffer
and the like to the context which gets used within the VM helps but there is one failing instanceof Object
check that I can't seem to work around (setting Object on the context doesn't work).
A simplified example of the problem can be seen by running:
vm.runInNewContext("test = {}; test instanceof Object", {Object:Object})
The above returns false when it should return true.
Here's a better example of the issue. comp
returns false when it should return true (at least it should for the new crypto library to function properly).
vm.runInNewContext("comp({})", {comp: (obj) => { return obj instanceof Object }})
I think I tried peculiar/webcrypto
a while back with some JWT related scenarios and it didn't work well. Would be worth confirming this scenario should this PR proceed.
const password = 'test';
const plainText = 'foo';
const ptUtf8 = new TextEncoder().encode(plainText);
const pwUtf8 = new TextEncoder().encode(password);
const pwHash = await crypto.subtle.digest('SHA-256', pwUtf8);
const iv = crypto.getRandomValues(new Uint8Array(12));
const alg = { name: 'AES-GCM', iv: iv };
const encKey = await crypto.subtle.importKey('raw', pwHash, alg, false, ['encrypt']);
const encBuffer = await crypto.subtle.encrypt(alg, encKey, ptUtf8);
const decKey = await crypto.subtle.importKey('raw', pwHash, alg, false, ['decrypt']);
const ptBuffer = await crypto.subtle.decrypt(alg, decKey, encBuffer);
const plainText2 = new TextDecoder().decode(ptBuffer);
if (plainText !== plainText2) {
throw new Error(':(');
}