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

1

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

Comments

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?

3 Comments

yeah $rsa->loadKey() also works it doesn't make any difference. for PKCS as I commented out it gives same error unfortunately
Did you try it without the strrev?
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; }
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.

2 Comments

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
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)'.
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).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.