Unable to send CryptoKey to Express server

227 views Asked by At

On the client I am generating a CryptoKeyPair object using the WebCrypto API. I want to send this key pair to my express server using the fetch API, but all I get in req.body is an empty object. Why this is happening?

Generating keys:

const keyPair = await crypto.subtle.generateKey(RsaOaepParams, true, ["encrypt", "decrypt"]);

POST request:

fetch('/', {
    method: 'POST',
    body: JSON.stringify(keyPair.publicKey),
    headers: {
      'Content-Type': 'application/json'
    },
})

No, this is not a problem with the bodyParser middleware. I have configured it properly. JSON.stringify(keyPair.publicKey) itself is turning the object empty

1

There are 1 answers

0
John Hanley On

To access the RSA Public Key requires several items:

  • The correct algorithm: RSA-OAEP
  • Exporting the public in the correct format ("jwk", or "spki")

Note: Your example code expects the JWK format. Typically, public keys are exported in SPKI format. See the second example.

JWK format for exporting a public key:

const params = {
        name: "RSA-OAEP",
        modulusLength: 2048,
        publicExponent: new Uint8Array([1, 0, 1]),
        hash: "SHA-256"
}

const keyPair = await crypto.subtle.generateKey(
                                        params,
                                        true,
                                        ["encrypt", "decrypt"]);

const pubKey = await crypto.subtle.exportKey(
                                        "jwk",
                                        keyPair.publicKey);

fetch('/', {
        method: 'POST',
        body: JSON.stringify(pubKey),
        headers: {
                'Content-Type': 'application/json'
        },
})


function ab2str(buf) {
        return String.fromCharCode.apply(null, new Uint8Array(buf));
}

SPKI format for exporting a public key:

const params = {
        name: "RSA-OAEP",
        modulusLength: 2048,
        publicExponent: new Uint8Array([1, 0, 1]),
        hash: "SHA-256"
}

const keyPair = await crypto.subtle.generateKey(
                                        params,
                                        true,
                                        ["encrypt", "decrypt"]);

const pubKey = await crypto.subtle.exportKey(
                                        "spki",
                                        keyPair.publicKey);

const b64 = btoa(ab2str(pubKey));

var pem = `-----BEGIN PUBLIC KEY-----\n${b64}\n-----END PUBLIC KEY-----`;

key = {
        "public_key": pem
}

fetch('/', {
        method: 'POST',
        body: JSON.stringify(key),
        headers: {
                'Content-Type': 'application/json'
        },
})