I'm working on a simple proof of concept to export and import private and public keys through node.js and browser communication using SubtleCrypto. I've installed the @peculiar/webcrypto package to keep things consistent between the front and backend. The first part is simply the generation and export of the keys, and the second part is my attempt to import the keys. Here is the code:
// GENERATE AND EXPORT KEYS
const { publicKey, privateKey } = await crypto.subtle.generateKey(
{
name: 'RSA-OAEP',
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: 'SHA-256',
},
true,
['encrypt', 'decrypt'],
);
const publicExport = await crypto.subtle.exportKey('spki', publicKey);
const privateExport = await crypto.subtle.exportKey('pkcs8', privateKey);
const pubExportedAsString = ab2str(publicExport);
const pubExportedAsBase64 = btoa(pubExportedAsString);
const publicKeyPem = `${pubExportedAsBase64}`;
const privExportedAsString = ab2str(privateExport);
const privExportedAsBase64 = btoa(privExportedAsString);
const privateKeyPem = `${privExportedAsBase64}`;
// IMPORT KEYS
const pubKeyImportedAsString = atob(publicKeyPem);
const pubKeyImportedAsArrayBuffer = str2ab(pubKeyImportedAsString);
const publicKeyImport = await crypto.subtle.importKey(
'spki', pubKeyImportedAsArrayBuffer, { name: 'RSA-OAEP', hash: 'SHA-256' }, true, ['encrypt']
);
const privateKeyImportedAsString = atob(privateKeyPem);
const privateKeyImportedAsArrayBuffer = str2ab(privateKeyImportedAsString);
const privateKeyImport = await crypto.subtle.importKey(
'pkcs8', privateKeyImportedAsArrayBuffer, { name: 'RSA-OAEP', hash: 'SHA-256' }, true, ['decrypt']
);
// HELPERS
const ab2str = (buffer: ArrayBuffer): string => new TextDecoder().decode(buffer);
const str2ab = (text: string): ArrayBuffer => new TextEncoder().encode(text);
The import of the keys is where this throws an error:
Unhandled error Error: Too big integer
I can't seem to see where the issue is, and why the key encoding and decoding would fail. If anyone has any clues or ideas, that would help out tremendously :)
Figured it out (for anyone in a similar predicament). Turns out the issue was the ab2str and str2ab helper functions, I was misled to believe TextDecoder/TextEncoder would properly handle the conversions for this use case.
Rewriting these to the following solved this issue!