Hello,
I want to use the ECDH algorithm to exchange public keys, then obtain the same derivedKey for client and server, then crypt / encrypt their messages, so my PWA is using End-to-End encryption.
My code works 100% fine in Chrome, on both client and simulated server on client.
When I try the code for real on server, especially when I generate a ECDH key pair (privateKey / publicKey), I receive the following error message from my Cloudflare Worker :
Unrecognized or unimplemented key generation algorithm requested
Is there anything I can do to bypass this error ?
Regards,
–
EDCH module
const name = 'ECDH';
const namedCurve = 'P-256'; // P-256, P-384, P-521
const usage: KeyUsage[] = ['deriveKey']; // deriveKey, deriveBits
const aes = {
name: 'AES-GCM', // AES-CTR, AES-CBC, AES-CMAC, AES-GCM, AES-CFB, AES-KW, ECDH, DH, HMAC
length: 256, // 128, 192, 256
};
const aesUsage: KeyUsage[] = ['encrypt', 'decrypt'];
// https://github.com/diafygi/webcrypto-examples#ecdh
export const keys = async () => {
const o = await crypto.subtle.generateKey({ name, namedCurve }, true, usage)
return { publicKey: await exportKey(o.publicKey), privateKey: await exportKey(o.privateKey) };
}
export const deriveKey = async (privateKey, publicKey) => {
const _private = await importPrivateKey(privateKey);
const _public = await importPublicKey(publicKey);
const cryptoKey = await crypto.subtle.deriveKey({ name, namedCurve, public: _public } as any, _private, aes, true, aesUsage);
return ab2hex(await crypto.subtle.exportKey('raw', cryptoKey));
}
// "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
const exportKey = async (cryptoKey) => JSON.stringify(await crypto.subtle.exportKey('jwk', cryptoKey));
const importPublicKey = async (key) => importKey(key, true);
const importPrivateKey = async (key) => importKey(key, false);
const importKey = async (key, isPublic) => crypto.subtle.importKey('jwk', JSON.parse(key), { name, namedCurve }, true, isPublic ? [] : usage);
const ab2hex = async (ab) => [...new Uint8Array(ab)].map(b => b.toString(16).padStart(2, '0')).join('');
–
Test code
const main = async () => {
const ecdh = (await import('crypto-ecdh'));
const clientKeys = await ecdh.keys();
console.log({ clientKeys });
const serverKeys = await ecdh.keys();
console.log({ serverKeys });
const clientDerivedKey = await ecdh.deriveKey(clientKeys.privateKey, serverKeys.publicKey);
console.log({ clientDerivedKey });
const serverDerivedKey = await ecdh.deriveKey(serverKeys.privateKey, clientKeys.publicKey);
console.log({ serverDerivedKey });
}
main();