2

I'm trying to encrypt a JSON string in C# en decrypt it in PHP by using OpenSSL RSA.

The following code is in C#:

public static string EncryptData(string data)
{
    string key = @"-----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/J/txQvYBm5iOHRRRtgdXd5hq
    DEavxy5OExSiwjJgOgT72A9GX7+E7QYfhUZJTGtf+/J84tuJPx6/Ff1dZa1XRW84
    /n5m7fw93CTVwpfRFi0Owenor44zgk6ABSfMlCzwGfdcS8AFiWCFUBpatKte6PaO
    /WfYK7qz/5faSp3FawIDAQAB
    -----END PUBLIC KEY-----";

    OpenSSL.Crypto.CryptoKey pKey = OpenSSL.Crypto.CryptoKey.FromPublicKey(key, null);
    OpenSSL.Crypto.RSA rsa = pKey.GetRSA();

    byte[] encryptedData = rsa.PublicEncrypt (Encoding.UTF8.GetBytes(data), OpenSSL.Crypto.RSA.Padding.PKCS1);
    rsa.Dispose();
    return Convert.ToBase64String (encryptedData);
}

then I send the encoded encryptedData to PHP and put it into the PrivateKeyDecrypt function.

Code in PHP:

<?php
// include the lib
//require_once('OpenSSL.php');

$ssl = new OpenSSL();
$ssl->loadPrivateKeyWithoutPath('-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQC+wVuIECnd7dvt7yqoElg4DL8jSKFpUavKfviSBE2Z+5z5YWnf
i4mp/r0P0jVbE+dfqReaIr4UOt//hPvwvioAJ576KPOCTYZiIGehkqafGWS+01wH
nAPSj/C7Xt7F9Mh5McH4CnBR5VN93KKZtQtfNsNPPBdXwQuquONOUgUgTwIDAQAB
AoGAIQkvpvLVrV/CVQS0qIL00FA00hGEEs9YJyuyNOeV4PMYjn/2bAaogs5hQ9ot
72YVDhYkxkb6EFrZ7FDFqT3l2/BpQEsJ6/GQq2gX0rYGfJ5sWrN+KIuSJr4FWSN+
LrvIEr35hKHY6mytiQg9D58b5kSjaB9ea/qhh/hJL2VfWGECQQDlBBJsccR2ZzzH
QN5omwFrUuxnqraY5LyZB8xUnqo9iDULO+GTcW/5eO9TBoWuDf1Ul3Snts9Tb+uD
UYL1y5onAkEA1Ts182anQHCjUtp2hooLjDcOvIK3gi5TchqHW6T4K3tNtnbfOB9P
gMNgcKljjXlQXl3ornvLTYBC483MS4RpmQJAZMiS9whmBhlOpP1GI1C7oih/Auwc
qVJYMRw+bqrYjnWnqkby8XkFZwsyfx4qrDtZ1eVFIB2SRczGHyc688JjFwJBAIxa
lx6J2VlfSwIEbrQMNaGrs/V9jVERMTgQIjy+j+P/G54ZDMEiSvCUqew+cxryWWZk
Jf6D2cQ/wsez9N9YXzECQQDMH6jS9vp7aabI2UKy5RhTqvP6kRmi28/GHb/8QrFx
tldiw2THvc4+4QT9tuv5OA6xRnEO5mt5u3vFHciqeRR7
-----END RSA PRIVATE KEY-----');

public function PrivateKeyDecrypt($raw_data, $base64 = TRUE)
{
    if ($this->privateKey == NULL)
        trigger_error("Private key has not been specified.", E_USER_ERROR);

    if (!openssl_private_decrypt(($base64) ? base64_decode($raw_data) : $raw_data, $decrypted_data, $this->privateKey, $this->padding))
        trigger_error("Unable to decrypt data.", E_USER_ERROR);

    return $decrypted_data;
}

The error I get when I call the PrivateKeyDecrypt function is:

FATAL ERROR: unable to decrypt data in ...

Does anyone have any idea what causes this error?

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
Bottleneck
  • 85
  • 7
  • Could you display the result of `openssl_error_string` and display the value of `this.padding`? Where is `loadPrivateKeyWithoutPath` defined? – Maarten Bodewes May 04 '14 at 23:19
  • PrivateKeyDecrypt is defined in OpenSSL.php which is included into this php file. this->padding is empty. Openssl_error_string: 04065076:rsa routines:RSA_EAY_PRIVATE_DECRYPT:unknown padding type – Bottleneck May 05 '14 at 08:20
  • @user3160232 - I'm not sure why you were downvoted. It seems like a question that could benefit future users. You attempted to solve the problem on your own. And you supplied the relevant code you tried. Keep up the good effort. – jww May 05 '14 at 14:20
  • @jww That was me with the downvote. IMHO it is reasonable to expect from a developer that he tries to make the parameters of the method call match on both sides. PKCS1 was explicitly specified in the C# call. – Maarten Bodewes May 07 '14 at 17:07
  • @owlstead - please forgive my ignorance. According to the PHP docs on [openssl_private_decrypt](http://www.php.net/manual/en/function.openssl-private-decrypt.php), the default padding is `OPENSSL_PKCS1_PADDING`. The PHP code only shows `$this->padding`. How did you make the leap that the PHP padding was wrong? – jww May 07 '14 at 19:01
  • @jww Well, it wasn't a length error, and since the algorithm accepts any message, there is actually nothing else that can indicate a decryption error. So either the key is wrong or the unpadding failed. I'll remove the downvote though, because PKCS#1 was apparently given as the default (hoping that the user will also take the hint and vote my answer up or accept it ;) ). – Maarten Bodewes May 07 '14 at 20:54

1 Answers1

0

Make your padding match OpenSSL.Crypto.RSA.Padding.PKCS1 in your C# code.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Thanks for your reply again. I'm new to all of this. Could you explain this in a bit more detail? – Bottleneck May 05 '14 at 09:18
  • Please try a different setting for `this->padding` yourself, preferably one that indicates PKCS#1 v1.5. – Maarten Bodewes May 05 '14 at 13:41
  • By manually setting the padding and converting all my information to Base64 strings I managed to get it to work. Thanks for pointing me out into the right direction! :) – Bottleneck May 07 '14 at 09:51