Unwrap and decrypt using crypto.subtle with a NodeJS-generated private key

Viewed 405

I'm generating a key pair on the server like this:

crypto.generateKeyPair('rsa', {
    modulusLength: 4096,
    publicKeyEncoding: {
        type: 'spki',
        format: 'pem'
    },
    privateKeyEncoding: {
        type: 'pkcs8',
        format: 'pem',
        cipher: 'aes-256-cbc',
        passphrase: password,
    }
}, callback);

I want to use this key on the client. What I tried is

function pad(arr, blocksize) {
    if (arr.length % blocksize === 0) return arr;
    let res = new Uint8Array(Math.floor(arr.length / blocksize) * blocksize + blocksize);
    res.set(arr, 0);
    for (let i = arr.length; i < res.length; i++) {
        res[i] = res.length - arr.length;
    }
    return res;
}

let ek = privateKey;
let h = "-----BEGIN ENCRYPTED PRIVATE KEY-----\n";
let f = "\n-----END ENCRYPTED PRIVATE KEY-----\n";
ek = atob(ek.substring(h.length, ek.length - f.length).split("\n").join(""));
ek = Uint8Array.from(ek, c => c.charCodeAt(0));
let pwd = password;
pwd = Uint8Array.from(pwd, c => c.charCodeAt(0));
let padded = pad(pwd, 32);
let pwdKey = await crypto.subtle.importKey(
    "raw",
    padded,
    {
        name: "AES-CBC",
        length: 256
    },
    false, ["unwrapKey"]
);
console.log(pwdKey);
let unwrapped = await crypto.subtle.unwrapKey(
    "pkcs8",
    ek,
    pwdKey,
    {
        name: "AES-CBC",
        length: 256,
        iv: crypto.getRandomValues(new Uint8Array(16))
    },
    {
        name: "RSA-PSS",
        hash: "SHA-512",
        publicExponent: new Uint8Array([1, 0, 1]),
        modulusLength: 4096
    },
    false, ["decrypt"]
);
console.log(unwrapped);

I also tried padding the private key, it didn't work.

But unwrapping fails with DOMException and no explanation. Any ideas as to how to make it work?

0 Answers
Related