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

crypto.publicDecrypt() won't decrypt data with a public key object #30268

Closed
Justin-Hubdoc opened this issue Nov 5, 2019 · 1 comment
Closed
Labels
crypto Issues and PRs related to the crypto subsystem. duplicate Issues and PRs that are duplicates of other issues or PRs.

Comments

@Justin-Hubdoc
Copy link

Justin-Hubdoc commented Nov 5, 2019

  • version:v12.6.0
  • platform: Darwin LM-C02XM0H9JG5M 18.6.0 Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDT 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 x86_64
  • subsystem:crypto

When publicDecrypt is passed a public key as a KeyObject, it throws an error:

Invalid key object type public, expected private.

When the same key is passed as a string, the decryption works correctly.

The code block below shows my usage of privateDecrypt(), privateEncrypt(), publicEncrypt() and publicDecrypt()

const crypto = require('crypto');

const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
  modulusLength: 4096
});

const privateKeyString = privateKey.export({ format: 'pem', type:  'pkcs1'});
const publicKeyString = publicKey.export({ format: 'pem', type:  'pkcs1'});

const privateKeyObject = crypto.createPrivateKey(privateKeyString);
const publicKeyObject = crypto.createPublicKey(publicKeyString);


function publicEncryptPrivateDecrypt(pubKey, privKey, message) {
  try {
    const toEncryptBuffer = Buffer.from(message);
    const encrypted = crypto.publicEncrypt(pubKey, toEncryptBuffer).toString("base64");

    const toDecryptBuffer = Buffer.from(encrypted, 'base64');
    const decrypted = crypto.privateDecrypt(privKey, toDecryptBuffer).toString("utf-8");
    console.log(decrypted === message);
  } catch (e) {
    console.log(e.message)
  }

}

function privateEncryptPublicDecrypt(pubKey, privKey, message) {
  try {
    const toEncryptBuffer = Buffer.from(message);
    const encrypted = crypto.privateEncrypt(privKey, toEncryptBuffer).toString("base64");
    const toDecryptBuffer = Buffer.from(encrypted, 'base64');
    const decrypted = crypto.publicDecrypt(pubKey, toDecryptBuffer).toString("utf-8");
    console.log(decrypted === message);
  } catch (e) {
    console.log(e.message)
  }
}

console.log("=====Testing public encrypt/private decrypt=====")
//Use objects generated by generateKeyPairSync()
publicEncryptPrivateDecrypt(publicKey, privateKey, "something to encrypt");
//Use strings generated by keyObject.export()
publicEncryptPrivateDecrypt(publicKeyString, privateKeyString, "something to encrypt");
//Use objects generated by createPublicKey() / createPrivateKey()
publicEncryptPrivateDecrypt(publicKeyObject, privateKeyObject, "something to encrypt");

console.log("=====Testing private encrypt/public decrypt=====")
//Use objects generated by generateKeyPairSync()
privateEncryptPublicDecrypt(publicKey, privateKey, "something to encrypt");
//Use strings generated by keyObject.export()
privateEncryptPublicDecrypt(publicKeyString, privateKeyString, "something to encrypt");
//Use objects generated by createPublicKey() / createPrivateKey()
privateEncryptPublicDecrypt(publicKeyObject, privateKeyObject, "something to encrypt");

//Use pass private key instead of public key because the documentation mentions:
// "Because RSA public keys can be derived from private keys, a private key may be passed instead of a public key."
//Use objects generated by generateKeyPairSync()
privateEncryptPublicDecrypt(privateKey, privateKey, "something to encrypt");
//Use strings generated by keyObject.export()
privateEncryptPublicDecrypt(privateKeyString, privateKeyString, "something to encrypt");
//Use objects generated by createPublicKey() / createPrivateKey()
privateEncryptPublicDecrypt(privateKeyObject, privateKeyObject, "something to encrypt");

Running the above yields the aforementioned error message when
privateEncryptPublicDecrypt(publicKey, privateKey, "something to encrypt");
and
privateEncryptPublicDecrypt(publicKeyObject, privateKeyObject, "something to encrypt");
are called.

@bnoordhuis
Copy link
Member

Duplicate of #30237 and being addressed in #30249. Thanks anyway for the report. :)

@bnoordhuis bnoordhuis added crypto Issues and PRs related to the crypto subsystem. duplicate Issues and PRs that are duplicates of other issues or PRs. labels Nov 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crypto Issues and PRs related to the crypto subsystem. duplicate Issues and PRs that are duplicates of other issues or PRs.
Projects
None yet
Development

No branches or pull requests

2 participants