Closed
Description
- 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.