Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decrypting SubtleCrypto.wrapkey() key received from browser #2109

Closed
shantanuthatte opened this issue Aug 7, 2019 · 2 comments
Closed

Decrypting SubtleCrypto.wrapkey() key received from browser #2109

shantanuthatte opened this issue Aug 7, 2019 · 2 comments

Comments

@shantanuthatte
Copy link

  • Node.js Version: v10.16.0
  • OS: Windows 10 Pro
  • Scope (install, code, runtime, meta, other?): code
  • Module (and version) (if relevant): crypto

Hi,

I'm trying to generate a key-pair in browser (to sign a message), send the generated public key using wrapKey and server's public key. Then decrypt this in node and verify the message.

I'm having issues, decrypting the received encrypted key, which results in Error: error:04099079:rsa routines:RSA_padding_check_PKCS1_OAEP_mgf1:oaep decoding error.

Generating server keys (and sending the public key to browser):

const { generateKeyPair } = require('crypto');
generateKeyPair('rsa', {
    modulusLength: 4096,
    publicKeyEncoding: {
        type: 'spki',
        format: 'pem'
    }, 
    privateKeyEncoding: {
        type: 'pkcs1',
        format: 'pem'
    }
}, (err, publicKey, privateKey) => {
    console.log(privateKey);
    console.log(publicKey); //Send this to client
});

Client code (Chrome 76.0.3809)

let publicKey = "MIICIj ... EAAQ=="; //As parsed
let payload.message = "Hello World";
let enc = new TextEncoder();

// Import server's key
let serverPublicKey = await crypto.subtle.importKey(
    "spki",
    str2ab(window.atob(publicKey)),
    {
        name: "RSA-OAEP",
        hash: "SHA-256"
    },
    false,
    ["encrypt","wrapKey"]
);

// Generate key
let keyToSignWith = await window.crypto.subtle.generateKey({
    name: "RSA-PSS",
    modulusLength: 2048,
    publicExponent: new Uint8Array([1,0,1]),
    hash: "SHA-256"
}, true, ["sign","verify"]);

// Wrap generated public key using server's public key
let encryptedKey = await window.crypto.subtle.wrapKey(
    "spki",
    keyToSignWith.publicKey,
    serverPublicKey,
    {
        name: "RSA-OAEP"
    }
);

payload.key = ab2str(encryptedKey);
let signature = await window.crypto.subtle.sign({
    name: "RSA-PSS",
    saltLength: 32
},
keyToSignWith.privateKey,
enc.encode(message)
);
payload.digitalSignature = ab2str(signature);

//Send `payload` to server via AJAX

Server request handler

const PRIVATE_KEY = `-----BEGIN RSA PRIVATE KEY-----
MIIJK ...
... V64dOQZ
-----END RSA PRIVATE KEY-----`;
let decryptedKey = crypto.privateDecrypt({
        key: PRIVATE_KEY,
},Buffer.from(body["key"],'base64'));

This step fails with Error: error:04099079:rsa routines:RSA_padding_check_PKCS1_OAEP_mgf1:oaep decoding error

What am I doing wrong?

@bnoordhuis
Copy link
Member

I'm reasonably sure you can't do that right now with Node.js v10.x. Some of the features you need for WebCrypto interop are really recent, e.g., nodejs/node#26960 and nodejs/node#28335.

@tniessen
Copy link
Member

You seem to use RSA-OAEP with SHA-256, this requires setting the oaepHash option in crypto.privateDecrypt, which was introduced by one of the PRs that @bnoordhuis mentioned. Please let us know if you need further assistance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants