3

I'm trying to build a simple RSA encryption decrpytion process between C# and PHP. I've accomplished encrypting in PHP and decrpyt in C# with phpseclib(http://phpseclib.sourceforge.net/). However I'm getting "Decryption error in C:\xampp\htdocs\Crypt\RSA.php on line 2103" which is this part:

if ($lHash != $lHash2) {
        user_error('Decryption error', E_USER_NOTICE);
        return false;
    }

the encryption in C# I used this bunch of code:

RSACryptoServiceProvider rsaCryptoServiceProvider = new RSACryptoServiceProvider(dwKeySize);
        rsaCryptoServiceProvider.FromXmlString(publickey);
        int keySize = dwKeySize / 8;
        byte[] bytes = Encoding.UTF32.GetBytes(inputString);
        // The hash function in use by the .NET RSACryptoServiceProvider here is SHA1
        // int maxLength = ( keySize ) - 2 - ( 2 * SHA1.Create().ComputeHash( rawBytes ).Length );
        int maxLength = keySize - 42;
        int dataLength = bytes.Length;
        int iterations = dataLength / maxLength;
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i <= iterations; i++)
        {
            byte[] tempBytes = new byte[(dataLength - maxLength * i > maxLength) ? maxLength : dataLength - maxLength * i];
            Buffer.BlockCopy(bytes, maxLength * i, tempBytes, 0, tempBytes.Length);
            byte[] encryptedBytes = rsaCryptoServiceProvider.Encrypt(tempBytes, true);
            // Be aware the RSACryptoServiceProvider reverses the order of encrypted bytes after encryption and before decryption.
            // If you do not require compatibility with Microsoft Cryptographic API (CAPI) and/or other vendors.
            // Comment out the next line and the corresponding one in the DecryptString function.
            Array.Reverse(encryptedBytes);
            // Why convert to base 64?
            // Because it is the largest power-of-two base printable using only ASCII characters
            stringBuilder.Append(Convert.ToBase64String(encryptedBytes));
        }
        string ciphertext = stringBuilder.ToString();

and my basic PHP code to decrpyt:

$rsa->loadKeyfromXML($privatekey);  
$ciphertext = file_get_contents('cipher.txt');
$ciphertext = base64_decode(strrev($ciphertext));

//$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);

$plaintext = $rsa->decrypt($ciphertext);

I've tried PKC1 it also gave another error in Crypt/RSA.php

relativelyPrime
  • 151
  • 1
  • 8

4 Answers4

2

yay I just found solution myself. I changed the line in encryption:

byte[] bytes = Encoding.UTF32.GetBytes(inputString);  ==> byte[] bytes = Encoding.Default.GetBytes(inputString);

and also as @Ryan said:

$ciphertext = base64_decode(strrev($ciphertext));  ==> $ciphertext = strrev(base64_decode($ciphertext));

Thanks for your attemps.

relativelyPrime
  • 151
  • 1
  • 8
0

Since you're doing Array.Reverse in C# I'd hazard to guess the strrev in PHP is unnecessary.

Also, phpseclib's Crypt_RSA has no loadKeyfromXML. Where are you getting that from? Doing $rsa->loadKey() should be sufficient.

Finally, my guess would be PKCS1 is required. What's the error you're getting when you use it?

neubert
  • 15,947
  • 24
  • 120
  • 212
  • yeah $rsa->loadKey() also works it doesn't make any difference. for PKCS as I commented out it gives same error unfortunately – relativelyPrime Apr 03 '13 at 21:53
  • Did you try it without the `strrev`? – neubert Apr 03 '13 at 21:56
  • yeap I also tried with/out strrev and base64_decode. still giving error at same line in RSA.php Also when I use PKCS1 I'm getting error at line: if (ord($em[0]) != 0 || ord($em[1]) > 2) { user_error('Decryption error', E_USER_NOTICE); return false; } – relativelyPrime Apr 04 '13 at 10:01
0

It seems to me that in PHP, you are taking the Base64-encoded ciphertext, reversing that, and then trying to Base64-decode it? I would think that you want to decode it first, then reverse the result. They aren't the same thing.

Whether any of this reversing is necessary in the first place, I can't say.

Ryan M
  • 2,072
  • 11
  • 14
  • yeah i just taken code from source that's why using reversing. For base64 encrypting from php and decrypting in C# worked well for that that's I used same operation – relativelyPrime Apr 03 '13 at 21:52
  • Tried decode first then strrev with(out) PKCS1 still giving error at same line without PKCS1 and with PKCS1 it gives error at: 'if (ord($em[0]) != 0 || ord($em[1]) > 2)'. – relativelyPrime Apr 04 '13 at 10:25
0

I have to say I did not completely get your problem, but it seems to be of how to combine RSA encryption in C# and PHP. I also had some trouble doing so, and for everybody still interested, I wrote a working project doing this, the C# program and PHP script both create RSA keys and exchange them and then communicate encrypted (see here).

Oliver
  • 118
  • 11