1

I was searching for a solution but i can't find a functional solution. I need to transmit a string(AESkey) from C# app to PHP server. The client(in C#) download a key.public.pem file(public key) and encrypt the pass, and later send it to the server. The server takes key.pem file(private key).

Server in PHP:

function RSADecryption($text) {
    //re() reads a document an return it as string
    openssl_private_decrypt(base64_decode($text), $decrypted,re("key.pem"));
    return $decrypted;
}

Client in C#:

using System;
using System.Text;
using System.Security.Cryptography;


namespace myApp
{
    class MyRSA
    {
        public static MyRSA getMyRSA()
        {
            if (_Instance == null)
            {
                _Instance = new MyRSA();
            }
            return _Instance;
        }
        public Boolean setPubKey(string url)
        {
            System.Net.WebClient wc = new System.Net.WebClient();
            try
            {
                publicKey = wc.DownloadString(url);
            }
            catch(Exception e)
            {
                return false;
            }
            return true;

        }
        public string crypt(string text)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            RSAParameters rsaParam = rsa.ExportParameters(false);
            rsaParam.Modulus = Convert.FromBase64String(publicKey.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", ""));
            rsa.ImportParameters(rsaParam);
            byte[] encValue = rsa.Encrypt(Encoding.UTF8.GetBytes(text), false);

            return Convert.ToBase64String(encValue);
        }


        private static MyRSA _Instance;
        private static string publicKey;

        private MyRSA() {}
    }
}

And later i do something like that from main:

MyRSA rsa = MyRSA.getMyRSA();
rsa.setPubKey(site+"key.public.pem");
sendData(rsa.crypt(user));

I think the problem is in the decrypter(PHP function) because doesn't return anything. I don't know but, maybe the problem is that you can't encrypt using RSACryptoServiceProvider and decrypt with openssl? Because they use diferents paramethers or other similars things?

For example, i generated this AES key:

cA?uW=kImEYGsgu

I use this public key

-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApxjhdfvCuafPZmE//cOM OVxBZvMXjwlcyaCfnTuVdbewQ5ITu6hlJ3vX/oTMbik7DprsWoc2tGk3Rx7RdAPd n3VnPm62QjaKtETWJ8/5Nzf+MxlVD0t5tzqzhniZ5BKZTtvCI6STbrFYnKcJwTyI eaEDNtre5EaqEBbrYhlGTRxNmz2SdRi9Im9iCSw9pjDVDDJdzmhENhASmFQMeo7N IS8AY3zJSjOQPKFymZrSa8hxWp88K1/igxs12IhhpqNjMiUi29gH2T+QLPTDzwEq EHTY1K6B0zlNuyp8HR5pNOqYymdnoSpCV3z0deTobAF7KiFYp2pXvoNo8Pc19Yl0 mQIDAQAB -----END PUBLIC KEY-----

And the encrypted password was:

CgG33ytbS3CuK+rOpJRamQ6e8xCj7Q35m6YxWXc44r/D03VubXZO1f5/zF7Zsc42UOOwqbYahApXBXL6o3J5MVu0cDkjstVoUnFJiPRHWmwq9AA0uvLC55gou+VzvmvRzFO38LMZ2BpsQLOjfv16LGWx7MLfKSVFGC8YVHgv6QlEbDFdd/HJDbqAKOoyQWlKXfVeMKmd8ORnq3+B3Tmk57O3BHDVOlmezSgf+YN828u4ChZ08JzjgBo7MP2xCl6pLEeZxiFGjRwrTgRfLXQ7aMB/RyeMMHwInJiTS3/M2Mez8C3/+Za/DIfrLDA9LVdRYdy2n4AxbtyrLTun4mjDO+pYS3HqZlGn2MW5Orc9VH+1CPn2omLVj/qqa6tIoFuJOdpxn/y9

Thanks for your atencion. Regards.

  • 1
    This is a - potentially - good question. At least very interesting. Could you please describe what you did to solve the problem on your own and at which point you are getting stuck? (Please *do not* describe it in the comments, but rather edit the question.) – Paul Kertscher Jan 06 '17 at 13:19
  • Is the private key actually being used in a production environment? If not I'd say post it. That way people can incorporate it into an answer for you. As is it's entirely possible the problem is something as simple as openssl doesn't support the format the private key is in. Without the private key it's really impossible to say. – neubert Jan 07 '17 at 18:02

1 Answers1

0

If your .PEM file says "BEGIN PUBLIC KEY", then it's probably an X.509 SubjectPublicKeyInfo structure. That means it looks like

30 xx  // SEQUENCE (SubjectPublicKeyInfo)
  30 0D  // SEQUENCE (AlgorithmIdentifier)
     06 09 2A 86 48 86 F7 0D 01 01 01  // OID (algorithm = rsaEncryption)
     05 00 // NULL (parameters)
  03 xx  // BIT STRING (subjectPublicKey)
     30 xx  // SEQUENCE (RSAPublicKey)
        02 xx [modulus value here]  // INTEGER (Modulus)
        02 xx [exponent value here]  // INTEGER (Exponent)

Which is a DER encoded blob. Each of the xx values represents a length, which could be more than one byte.

So when you're loading this key you're taking all of the overhead/structural content, as well as the modulus bytes AND the exponent bytes, and calling all of that Modulus. So the net effect is you are encrypting with a different public key than you are decrypting with.

.NET doesn't make reading PEM key contents easy. Your best bet is to turn this key into a certificate. If you don't already have a certificate you can do openssl req -x509 -new -key theprivatekey.pem -out selfsignedcert.cer (and answer whatever you like for the subject prompts).

Otherwise, you're now reduced to How to load the RSA public key from file in C# (and other related questions).

Community
  • 1
  • 1
bartonjs
  • 30,352
  • 2
  • 71
  • 111