3

i'm trying to create a WS for make soap request. In the body of the message there is a field that contains an encrypted text. I have the public key to encrypt the text but the only result that i obtain is that the text is not recognized. I use crypto module of node for making request and the text is crypted but i don't know why is not correclty encrypted.

Ps i made the same thing on php with openssl_public_encrypt function and working. But i have to do it in node.js.

Any idea or suggestion? What is different openssl_public_encrypt from crypto.publicEncrypt function?

Here is the encrypt part in node.js:

var crypto = require("crypto");
var fs = require('fs');

fs.readFile("./certificate.pem", 'utf8', function (err, data) {
    var bufferToEncrypt = new Buffer("textToEncrypt");
    var encrypted = crypto.publicEncrypt({"key":data, padding:crypto.RSA_NO_PADDING}, bufferToEncrypt).toString("base64");
    console.log(encrypted);  // length 128
}

The same thing in php:

<?php

    $publicKey = "./certificate.pem";
    $plaintext = "textToEncrypt";

    openssl_public_encrypt($plaintext, $encrypted, $publicKey);

    echo base64_encode($encrypted);   //encrypted string length 128

?>

I don't have the private key for decrypting the text, i only have the public key.

Also notice that the length of the encrypted text (in base64) is the same in php and in node.js.

AngelPoyel
  • 160
  • 1
  • 9
  • It is unlikely that anyone can help you here unless you include the actual code you are using for both encryption and decryption so we can see what you have and try to determine what you have done wrong. – jfriend00 Jan 22 '16 at 18:52
  • @jfriend00 You're right! I've updated the post with pieces of code for the encryption part – AngelPoyel Jan 22 '16 at 19:39

1 Answers1

10

I guess the padding is your problem. In node.js you specify padding:crypto.RSA_NO_PADDING. When looking up the doc of openssl_public_encrypt() it says that it uses OPENSSL_PKCS1_PADDING by default. Try the following:

var constants = require("constants");
var encrypted = crypto.publicEncrypt({"key":data,
    padding:constants.RSA_PKCS1_PADDING}, bufferToEncrypt).toString("base64");

I have prepared an online demo:

  1. Encrypt using node.js
  2. copy the resulting string
  3. and paste it to $encrypted_encoded on PHP decryption example

Advise: As a rule of thumb, don't use asymmetric encryption for actual messages. Use it to protect a symmetric key instead. However, your use case might be valid, I just want to state this every time someone talks RSA encryption.

Scolytus
  • 16,338
  • 6
  • 46
  • 69
  • Sorry but also changing the padding type, according to your solution, the encrypted text generated is not recognized by the system. – AngelPoyel Jan 23 '16 at 10:44
  • I see that the public key that i have is a certificate. Also i try to create a public key from this certificate using openssl, but not working – AngelPoyel Jan 23 '16 at 14:10
  • @AngelPoyel I'have fixed the code, unfortunately the constants were undefined, thus the padding was still wrong. I've also added some only demos for both node.js encryption and php decryption. – Scolytus Jan 28 '16 at 19:31
  • I try you new solution and now it work. Thanks a lot for your help – AngelPoyel Jan 28 '16 at 19:55