0

I'm trying to implement public-private key encryption/decryption for c# server and website. If I encrypt with the public key on PHP I can easily decrypt it using the private key, but when I encrypt the data in C# with the public key I cannot decrypt it with the private key on PHP. Basically, return nothing (or false from var_dump).

C#

var pkey = $"<RSAKeyValue>\r\n\t<Modulus>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsaxzQmdhvuM+yjJJgpVHUr0DW 3XbAr/sWbSdceanVX7IhccU8XCGurrM7rNYWhyIBzD8/RGGnqupfdt3rsNYvMKMO rU6thBEDBUVYJO58olDgW7ACbd/u95/0uRPzwGeqDQUn565iDfMyU6+jjaoGn7+D 5D0Bt8x6mLiu43y0zQIDAQAB</Modulus>\r\n\t<Exponent>AQAB</Exponent>\r\n</RSAKeyValue>";

//Encrypting the text using the public key
cipher = new RSACryptoServiceProvider();
cipher.FromXmlString(pkey);
byte[] data = Encoding.UTF8.GetBytes(message);
byte[] cipherText = cipher.Encrypt(data, false);
var encrypted = Convert.ToBase64String(cipherText);
Console.WriteLine(encrypted);

C# code image

From PHP

$rsa = new RSA();
$rsa->loadKey('MIICXQIBAAKBgQCsaxzQmdhvuM+yjJJgpVHUr0DW3XbAr/sWbSdceanVX7IhccU8/nXCGurrM7rNYWhyIBzD8/RGGnqupfdt3rsNYvMKMOrU6thBEDBUVYJO58olDgW7AC/nbd/u95/0uRPzwGeqDQUn565iDfMyU6+jjaoGn7+D5D0Bt8x6mLiu43y0zQIDAQAB/nAoGAXLIRgczUYew4LcQJhlAbGH9IGrxh9eIm2b3BZaQ7PG4AdJ6X7YWSzjk6PyEC/n0IXCMLlAX6FB50SqULy1PtuJql6HAGP5E1YLUxbgct/+JTC3Txy7jLlBRENyf4Nz/nj0oVvR+//vLLNc/MRl4g8gsCOvtTv4QWDkhvPYq0nLNkGHkCQQDkdiGs103RC5pf/n9/SUMq95bIpAS3jDOrjNKrHjTCYPzchExh1Q3qcyJWWCDgUVP4rUwk5NBYyJ/Glb/nRUDeXuQbAkEAwTOag7BbRguTjjcZeyHrbCPEaimpEClzdEWp6CPxGwHYcTWes74K/ncJrhesgy3ZTqVi4lILdNbpUvq1JjvwpJNwJAVplYxnWOb7EgQURyF0LnNPWpqhlx/nmz9FEbAfYfNZciAky7z1G9RqOB3ozlWWI6nEbEWC/LsfvKZLIWes4R3DBQJBAJq3/nOmtu1Qj4yEdA9JTYivDki6wAhLS+nQhlqTSPY8se5Tdzmw2RiEa4oQx0OdecIzS0/na2MRp16A9dWaeupH0G0CQQDii6l2MeVK4ImBqeEjycRQYRhRxLsiEA7ad0ptGvfC/nir/AowGmQ6jTmkMxp+zSFFCHS8ZHAAcBnZ3Ef5kA8SFY');
$convert = base64_decode("CkR7GLQZFUHLcFnhMGxsLYX/4rbrOM+NaXFLyTED3H+xbTChLsXRBQTGo7Xme44b4+/1c7SWahah/FI4gqFx5aDJ1olUmvUR/cto2X7QjBbIBJiFmXRAokbyyBBZ14v8iFqHwunv6Yc+5k/kO/fMK41mJn8xQms+K79CERkCASB7W3dxAFqh06Ksq/Mi9HwW0RakIsbHsdhu3hGQQy4d4h5J");
var_dump($rsa->decrypt($convert));

Note: Those keys are not real and they are generated for development purpose

Link to testing environment code

Teodor
  • 81
  • 1
  • 11
  • Make sure that you use the correct padding scheme and hash function for encryption and the padding scheme. – Artjom B. Apr 01 '17 at 18:11
  • Could you be more specific? I've used tutorial provided in both languages about implementation. – Teodor Apr 01 '17 at 18:18
  • it looks to me that pubic keys are different in php and c# – Sugumar Venkatesan Apr 01 '17 at 18:22
  • @vSugumar I've edited the post with an image from c# code. Basically ignored everything between brackets <>. Other that in c# is the public key and on PHP is the secret key – Teodor Apr 01 '17 at 18:42

1 Answers1

3

Wrong padding scheme

You have to use the exact same padding scheme for this to work.

The false in cipher.Encrypt(data, false) disables OAEP. So, PKCS#1 v1.5 padding will be used for encryption.

You have to set the following to use the same padding scheme:

$rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);

Broken keys

Keep in mind that you need to use proper keys for that. You seem to be using keys from here for testing purposes.

If we decode the public key, we get this in Hex:

modulus = 94 FB 56 CB 7C F9 9C 63 BA AB 17  F7 53 6C 0B 6E 26 5B F8 47 F1 55 73 55 84 1F D1  CA 53 48 D0 8D 7F E7 FD D6 FD BF 3F F1 D2 2D ED  7B F6 CA 2C D1 1C C1 48 41 BB E3 D6 3E 73 AD FE  A5 54 44 6F 41 51 3E 91 B0 24 45 52 7D 02 C8 68  94 2A 8C B8 E6 8F 4A FE 62 40 1E 66 EB 36 DA D4  07 A7 24 AD 82 C5 EF 96 39 D2 75 0D B0 15 47 50  3C 3C C9 0C A6 9A 23 81 4F 58 1C FC A3 39 B3 5C  53 CF 8E 0B 33
exponent = 01 00 01

We can use this tool to convert this Hex representation to a Base64 representation. Remember, do not transmit your private key if you want to transform it. Your public key for C# would look like this:

<RSAKeyValue><Modulus>lPtWy3z5nGO6qxf3U2wLbiZb+EfxVXNVhB/RylNI0I1/5/3W/b8/8dIt7Xv2yizRHMFIQbvj1j5zrf6lVERvQVE+kbAkRVJ9AsholCqMuOaPSv5iQB5m6zba1AenJK2Cxe+WOdJ1DbAVR1A8PMkMppojgU9YHPyjObNcU8+OCzM=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>

Now to your private key. PHP supports multiline strings. Use them! You tried to reduce your private key to a single line and because of that, you made a mistake. Newline characters are \n not /n.

Solution

C# example:

var pkey = "<RSAKeyValue><Modulus>lPtWy3z5nGO6qxf3U2wLbiZb+EfxVXNVhB/RylNI0I1/5/3W/b8/8dIt7Xv2yizRHMFIQbvj1j5zrf6lVERvQVE+kbAkRVJ9AsholCqMuOaPSv5iQB5m6zba1AenJK2Cxe+WOdJ1DbAVR1A8PMkMppojgU9YHPyjObNcU8+OCzM=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";

var cipher = new RSACryptoServiceProvider();
cipher.FromXmlString(pkey);
byte[] data = Encoding.UTF8.GetBytes("some message");
byte[] cipherText = cipher.Encrypt(data, false);
var encrypted = Convert.ToBase64String(cipherText);
Console.WriteLine(encrypted);

C# output:

kRyQsT55mQWmjQ0n1GbXOpaoMvng/BDNWk/0S2G4cqsKD1Fm7ktFdQIvnGlY6kbPXY0unwzGHbBpUGrALOITeyPHCRdsGIGVUc2O0lqI74QROloyoShXwX7TyAwzLJB6yiVSM7SDpy/6wJ5XkHLZRJu9KxmFrIBgOB9+b2x6C4A=

PHP example:

use \phpseclib\Crypt\RSA;

$private_key = "-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCU+1bLfPmcY7qrF/dTbAtuJlv4R/FVc1WEH9HKU0jQjX/n/db9vz/x0i3te/bK
LNEcwUhBu+PWPnOt/qVURG9BUT6RsCRFUn0CyGiUKoy45o9K/mJAHmbrNtrUB6ckrYLF75Y50nUN
sBVHUDw8yQymmiOBT1gc/KM5s1xTz44LMwIDAQABAoGAGsiMtAyFu23ac0PdvOuhqm3O/vXAF0Ki
zxwBVURfxM6LfiOOcRPe5RSKGTW+Cl7AQVEmMlsa/LtBhLhQ9LNQ5L/4oTmRhCGiZZEmccAdjKsx
yMeaxkp+ZHvMxMKQNDgYg1CXqrCrpwwUuMUlA26tfxZ3xSFtFyDTaV9mgDQ1IGECQQCkX9Tum7D1
vQTwbhbYnu7eC4eUOaZeGWSEs2csK7U6vfZ3BzUZW/0tPqcSpQqcNxMtY9TiUsNRj1uM6jX3byp7
AkEA6Ab+wvOTNRtES77OAYG9gHGZZ+iXjQJ/6Z7JehN4p41UbDIf9nNUOLUPL9z5V1uOYnl1CWoo
Cw95cdhKXxEAqQJBAIU5Or6tp250ZdVslM27ewSyuY9UblfkIsk/EscFIdzbbDAqwkmsefW6yvTc
mU3lgYCPYlKRG8c19tCuX1ENY5MCQAz37x9YW975Ai01ofAFn2DheJCNOINCI4IcROiU1AaRaKmP
d6fftFJjFFE5iZovXNr2LOt0yn4rxD7vtuBvY9kCQGyty6YCB6qaD7qXPMhLrLbGajAIWd6ETgxv
frK/BJu+buPfDky/g1FhI5R9iMtL1xH0JYLJlaVocU+xSeA9DkY=
-----END RSA PRIVATE KEY-----";

$rsa = new RSA();
var_dump($rsa->loadKey($private_key));
$rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
$convert = base64_decode("kRyQsT55mQWmjQ0n1GbXOpaoMvng/BDNWk/0S2G4cqsKD1Fm7ktFdQIvnGlY6kbPXY0unwzGHbBpUGrALOITeyPHCRdsGIGVUc2O0lqI74QROloyoShXwX7TyAwzLJB6yiVSM7SDpy/6wJ5XkHLZRJu9KxmFrIBgOB9+b2x6C4A=");
var_dump($rsa->decrypt($convert));

PHP output:

bool(true)
string(12) "some message"
Community
  • 1
  • 1
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • Sadly above does not work. It returns empty/false response. Would you like to setup a test environment on Github? I'd like to mention that my web environment is **Laravel 5.4 with composer installed phpseclib 2.4 version** – Teodor Apr 02 '17 at 09:27
  • Link to code https://bitbucket.org/Spartan01/rsa/src/178b1f34e30953ad01838e2d6fea1c66e67b5641?at=master – Teodor Apr 02 '17 at 09:42
  • I can't help you further, because I don't have PHP installed or even phpseclib configured. – Artjom B. Apr 02 '17 at 10:01
  • I've tried to parse your private key. It doesn't seem like it's a valid private key. It cannot be parsed as ASN.1. – Artjom B. Apr 02 '17 at 10:17
  • Thanks for the effort anyway. I've used the private(also public) key generated from phpseclib with small changed where empty space is replaced with /n or you will get decryption error.[From here](http://stackoverflow.com/a/15750784/7792888) – Teodor Apr 02 '17 at 10:48
  • I see what you did there. You haven't properly formatted the private key and you haven't properly formatted the public key. – Artjom B. Apr 02 '17 at 11:33
  • what do you mean? Can you show me how it should be? I've basically copied code example code on both languages. At least it should work if they are providing those examples. – Teodor Apr 02 '17 at 11:55
  • I'm either dumb or too tired following the steps because I'm getting this time Decryption error on BigInteger. To prevent comments turning into chat, would you mind show me HOW should be done on Bitbucket or email me @ teo.dragnev@gmail.com . If I manage it to work, I'll update my question with working code. I'm really sorry. – Teodor Apr 02 '17 at 12:42
  • Email me so I can give you credentials for a test environment. – Teodor Apr 02 '17 at 13:23
  • I've added the full code. I used phpseclib 2.0.4 (currently the highest version I could find). There was an issue with the constant. – Artjom B. Apr 02 '17 at 16:44
  • Work flawlessly. Thank you so much. I've been battling with this for 3 days. If there is a way to repay you back, please let me know. – Teodor Apr 02 '17 at 17:43