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.privateDecrypt cannot decrypt message #22792

Closed
Nolaan opened this issue Sep 10, 2018 · 16 comments
Closed

crypto.privateDecrypt cannot decrypt message #22792

Nolaan opened this issue Sep 10, 2018 · 16 comments
Labels
crypto Issues and PRs related to the crypto subsystem. doc Issues and PRs related to the documentations.

Comments

@Nolaan
Copy link

Nolaan commented Sep 10, 2018

  • Version: v8.11.3
  • Platform: Linux x86_64
  • Subsystem:

I'm trying to encrypt/decrypt data using a rsa key but the process fails somehow with this message :

Error: error:04099079:rsa routines:RSA_padding_check_PKCS1_OAEP_mgf1:oaep decoding error

Code :

var  childProcess = require('child_process');
var  crypto = require('crypto');

var pk;
var mess_chiffre;

var sign = function () {
  var buf = new Buffer("Coucou c'est relou!!!");
  var sig = crypto.privateEncrypt(pk,buf);
  mess_chiffre = sig.toString('hex');
  console.log("Signed : ", mess_chiffre);
};


var decrypt = function () {
  var buff = new Buffer(mess_chiffre,'hex')
  console.log('Buffer : ',buff)
  console.log('decrypting withh pk: ')
  console.log(pk)
  var mess = crypto.privateDecrypt(pk,buff)
  console.log(mess)
};


childProcess.exec('openssl rsa -in private.key', {},
    function (err, stdout, stderr) {
  if (err) throw err;
  pk = stdout; // Save in memory for later use
  sign();
  decrypt();
});
@addaleax addaleax added the crypto Issues and PRs related to the crypto subsystem. label Sep 10, 2018
@addaleax
Copy link
Member

@nodejs/crypto

@tniessen
Copy link
Member

Just so we are on the same page: Why are you trying to use privateDecrypt after applying privateEncrypt? That's not how asymmetric encryption works.

@mscdex
Copy link
Contributor

mscdex commented Sep 10, 2018

Yes, either privateEncrypt() needs to be publicEncrypt() or privateDecrypt() needs to be publicDecrypt().

@mscdex
Copy link
Contributor

mscdex commented Sep 10, 2018

Also, in the future please ask help questions such as this on the nodejs/help issue tracker.

@addaleax addaleax added the doc Issues and PRs related to the documentations. label Sep 10, 2018
@addaleax
Copy link
Member

I do think this should be mentioned in the docs, ideally with an example of how to do it “right”?

@Nolaan
Copy link
Author

Nolaan commented Sep 10, 2018

@tniessen So please provide a working example. From the docs I couldn't neither with publicEncrypt/privateDecrypt or otherwise.

@tniessen
Copy link
Member

const crypto = require('crypto');

const privateKey = `-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----`;

const publicKey = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0
FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/
3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQAB
-----END PUBLIC KEY-----`;

const plaintext = Buffer.from('Hello world!', 'utf8');

// This is what you usually do to transmit encrypted data.
const enc1 = crypto.publicEncrypt(publicKey, plaintext);
const dec1 = crypto.privateDecrypt(privateKey, enc1);
console.log(dec1.toString('utf8'));

// This works as well.
const enc2 = crypto.privateEncrypt(privateKey, plaintext);
const dec2 = crypto.publicDecrypt(publicKey, enc2);
console.log(dec2.toString('utf8'));

@Nolaan
Copy link
Author

Nolaan commented Sep 10, 2018

Thanks! But why would the private key be able to decrypt anything? Isn't it suppose to be just an encrypting key, the one you send to people?

@Nolaan
Copy link
Author

Nolaan commented Sep 10, 2018

@Nolaan Nolaan closed this as completed Sep 10, 2018
@tniessen
Copy link
Member

@Nolaan That's what the private key is usually for, yes, and publicEncrypt / privateDecrypt is much more common than the other pair of functions. However, some asymmetric ciphers (such as RSA) can be used in the other way as well.

@Nolaan
Copy link
Author

Nolaan commented Sep 10, 2018

Ok, I've lost it a bit in the docs because I saw :

Because RSA public keys can be derived from private keys, a private key may be passed instead of a public key.

So I thought I could just use the private key for symmetric encryption (encrypt/decrypt).

@tniessen
Copy link
Member

@Nolaan You can by passing the private key to publicDecrypt / publicEncrypt.

addaleax added a commit to addaleax/node that referenced this issue Sep 12, 2018
addaleax added a commit that referenced this issue Sep 17, 2018
Refs: #22792

PR-URL: #22820
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
targos pushed a commit that referenced this issue Sep 18, 2018
Refs: #22792

PR-URL: #22820
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
targos pushed a commit that referenced this issue Sep 19, 2018
Refs: #22792

PR-URL: #22820
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
targos pushed a commit that referenced this issue Sep 20, 2018
Refs: #22792

PR-URL: #22820
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
@popov654
Copy link

popov654 commented Sep 17, 2023

I have the exactly same problem. I created a pair of keys on server side with Node, transfered one to the client, encrypted a sample string, but when I try to decrypt it on the server, I get the following:

Error: error:04099079:rsa routines:RSA_padding_check_PKCS1_OAEP_mgf1:oaep decoding error at Object.privateDecrypt (node:internal/crypto/cipher:79:12) at Object.<anonymous> (/home/runner/Generate-Key-Pair/index.js:27:30) at Module._compile (node:internal/modules/cjs/loader:1101:14)

I am currently using repl.it for running Node JS code and Chrome Debugger console for running client side code.

Client side code is this:

const publicKeyHash = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx+6mliYZnAmJid8/u+SdiMdjB5BlNub4AsObrSG0v1AkmiiLL7N0WzN0+alClyXIOm12qQtYdHDaNkTr1xiO7ZYKH92y9S4g4PI5IIx6U7BNardEnvAS8YMh3HfuC/wMkkLiwuy/QvMPXL+Dp3eNzESJ69rMKkaEf5N2qZ39DbzA3//5PU7UlmhdjmMAr7h30cr5433mMR/NnuMJ+ZYWbZnlaeJKZFjWO2EkuzN2cheaIVxgi46pfdLnZfdxQE8TARgenw/5KdkVzaIk0y+eShEs+YA7hLYTI3iohthY0hgMv1+dd3TYzp/Nc3yqsyngXeQxa2pi4xTlmkXEiLtBeQIDAQAB';
 
const str2ab = str => {
    const buf = new ArrayBuffer(str.length);
    const bufView = new Uint8Array(buf);
    for (let i = 0, strLen = str.length; i < strLen; i++) {
      bufView[i] = str.charCodeAt(i);
    }
    return buf;
}
 
const generateKey =  async () => await window.crypto.subtle.generateKey(
    {
        name: "RSA-OAEP",
        modulusLength: 2048,
        publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
        hash: { name: "SHA-256" }
    },
    true,
    ["encrypt", "decrypt"]
);
 
const importKey = async (pem, opt) => {
    const binaryDerString = window.atob(pem);
    const binaryDer = str2ab(binaryDerString);
    return await window.crypto.subtle.importKey(
        "spki",
        binaryDer,
        {
            name: "RSA-OAEP",
            hash: "SHA-256"
        },
        true,
        opt
    );
}
 
const encryptMessage = async (key, msg) => {
    return await window.crypto.subtle.encrypt(
        {
            name: "RSA-OAEP"
        },
        key,
        str2ab(msg)
    )
}
 
const decryptMessage = async (key, msg) => {
    return await window.crypto.subtle.decrypt(
        {
          name: "RSA-OAEP"
        },
        key,
        msg
    );
}
 
function arrayBufferToBase64String(arrayBuffer) {
    var byteArray = new Uint8Array(arrayBuffer)
    var byteString = ''
    for (var i=0; i<byteArray.byteLength; i++) {
      byteString += String.fromCharCode(byteArray[i])
    }
    return btoa(byteString)
}
 
const test = async _ => {
    try{
        let publicKey = await importKey(publicKeyHash, ["encrypt"]);
 
        let msg = "Admin:Password";
        console.log("исходный текст для шифрования:", msg);
        let msgEncrypted = await encryptMessage(publicKey,  msg);
        console.log(arrayBufferToBase64String(msgEncrypted));

    }
    catch(e){
        console.log(e)
    }
}

Node JS code is this:

const crypto = require("crypto");

/*
crypto.generateKeyPair('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: {
        type: 'spki',
        format: 'pem'
    },
    privateKeyEncoding: {
        type: 'pkcs8',
        format: 'pem'
    }
}, (err, publicKey, privateKey) => {
    console.log(publicKey);
    console.log(privateKey);
});
*/

let privateKey = crypto.createPrivateKey('-----BEGIN PRIVATE KEY-----\
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDH7qaWJhmcCYmJ3z+75J2Ix2MHkGU25vgCw5utIbS/UCSaKIsvs3RbM3T5qUKXJcg6bXapC1h0cNo2ROvXGI7tlgof3bL1LiDg8jkgjHpTsE1qt0Se8BLxgyHcd+4L/AySQuLC7L9C8w9cv4Ond43MRInr2swqRoR/k3apnf0NvMDf//k9TtSWaF2OYwCvuHfRyvnjfeYxH82e4wn5lhZtmeVp4kpkWNY7YSS7M3ZyF5ohXGCLjql90udl93FATxMBGB6fD/kp2RXNoiTTL55KESz5gDuEthMjeKiG2FjSGAy/X513dNjOn81zfKqzKeBd5DFramLjFOWaRcSIu0F5AgMBAAECggEBAIARQuxTI3xsL4n9U1oMK0z+S1UBDZSJhrxeiE3ylVEnCQsmhWHc1d/FqlxyK5GeRhAHJkdKWTLdRyoUI+34cTWHMp0O6h9bmPv+rNFIquMIv85n7rDQn5HMqdgLipRqs7LM3Wx3Mly0TVbf5nlTf6UlEiPeV4GNAjqmPxCPfxVYe4jVncxYtGEpbid5gs5VU1kat411vmYNUZW7RjH1GYdI1nkuxjiNdMK3QvWGFj1ABkHGXpAyCG97w9zIdeCytBLPZ7HIF+0wIE+6DAu9KdG3uKbAf5td2FQiVsk9gBp+oG+0vfs/jo9f7Xq4TopMPTWOQuRFWGNu8O+dZfKS4DECgYEA/Z7pHL9CVkL9NcsXwHgnSEYMr5bwwFdeQ0T2zzEg9nAFZNOnAkLMmhC1jWr9ozT9esC4cpDmYRamd9HuEATIQi/ETvrbeERUYZAq55cEVxvZJwvGtOlKaW3bH7k+O+kdl07jvuGWsnqH3QSg/ISttwyc99RT9XjbrYKEex2E518CgYEAyc7NmCgltgCxPUWHJSRrDMWKhnM0pwju1vMgk5a/8Kqnwv7X+7aWnkXFMWu3/D8jIF3bFEKDpC7ZlAq0WwFfBtaGs/9WRtvbzP/cM5CPWeu9XOW9x7Yx2rn3IocU0uDvwcYedcVHDRa05nC5t9+6lcGC++kLkZWY+2mzJ2ptPicCgYEA1NYE3uEKdIWnJPuYpSawIJDYmIpc46zuKBm53cpm1SjQ/fo4j0crmKcpFNKSo+IWTmto3owHKbbuYGNGGx9IR3L6lSUkBNuizHVF7C/prohqRcA2MyAMGEnet9KnDXPmJ1JHAasi4gi995ao2wElHxZwq/H9u2R/Ri7fqsns/JUCgYA4RWPqg3dQcoz5SsPORYNcAlEIAGO0F7eRVCXHQYevscYphynuVBFXfJjpmOGqgmhnBASsd4eBZlbhAsMbhRxcKcFRu2bxRyjY1pcuAacXKbaZiq4KW/E2zhftFsFls7bmzzl7GVEggy5Z+yCt9sJuM5E0cNz68T3BDM4ZtYFUjQKBgQCvFU70gdcWhM4uYmSe3L4VBxdS53SaVIdtGCVKNCK5ZaJPqj+g5vL9KMpq9cQ4rl/rgGqo45WKNACvS3Q42+bMLyjUmMPyU9lLScp49RasXmK3sw/2CmQAsky793Zcf9MYIp1f11rcJBTlKrz3ZvBkjYeYpVAtWraB6sejZmPJGg==\
-----END PRIVATE KEY-----');

let data = 'PjEhLCjoPLc3ZXFE1VNga00KHFif+wtNfjIGCck/4SeLn3woDBhHP4cJCRdyqPajLLtUVMWUDZpEXfAh4Ch5hAB3+qI6mo+6n9NDBHv6/jH+sF7rl5XQCcbZyVOSIWtmzPr//eIWNUheg0YXweX9mgC9KeUpXvtIAY7LT5tnvaZpYJx1zyX3YP/4eIisjVMJbhuM1K8sakvAXparOwWg/TpCDPiFN68OOuWTgBju4tjbSy8iLKy5RecxhvuI1M6/4i2Cx3FWxqcNPgIgcjxXTzAPjYz3cqqDqQ4jORsHoJ9yOovWtNpP8xF4QwNj5n4Ci5mRmfs2g2Zs4stGvx1CEg==';



const decryptedData = crypto.privateDecrypt(
   privateKey,
   Buffer.from(data, 'base64')
);
console.log(decryptedData.toString());

What am I missing?

@popov654
Copy link

popov654 commented Sep 18, 2023

I also tried decrypting with no padding, it gave no errors but the result is garbage (not correct):

const decryptedData = crypto.privateDecrypt({
      key: privateKey,
      passphrase: '',
      padding: crypto.constants.RSA_NO_PADDING
   },
   Buffer.from(data, 'base64')
);
console.log(Buffer.from(decryptedData));

@AlastairTaft
Copy link

AlastairTaft commented Sep 21, 2023

@popov654

I think you're missing oaepHash

const decryptedData = crypto.privateDecrypt(
  {
    key: privateKey,
    oaepHash: 'SHA256'
  },
  Buffer.from(data, 'base64')
);

@popov654
Copy link

Thanks, that helped

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. doc Issues and PRs related to the documentations.
Projects
None yet
Development

No branches or pull requests

6 participants