加密C#&&使用PEM文件在PHP中解密

时间:2017-01-06 13:12:39

标签: c# php encryption rsa pem

我正在寻找解决方案,但我找不到功能性解决方案。 我需要将一个字符串(AESkey)从C#app传输到PHP服务器。 客户端(在C#中)下载key.public.pem文件(公钥)并加密传递,然后将其发送到服务器。 服务器获取key.pem文件(私钥)。

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;
}

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() {}
    }
}

后来我从main做了类似的事情:

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

我认为问题在于解密器(PHP函数),因为它不会返回任何内容。 我不知道但是,也许问题是您无法使用RSACryptoServiceProvider加密并使用openssl解密? 因为他们使用不同的参数或其他相似物吗?

例如,我生成了这个AES密钥:

  

CA?微瓦= kImEYGsgu

我使用这个公钥

  

-----开始公钥-----   MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApxjhdfvCuafPZmE // COM   OVxBZvMXjwlcyaCfnTuVdbewQ5ITu6hlJ3vX / oTMbik7DprsWoc2tGk3Rx7RdAPd   n3VnPm62QjaKtETWJ8 / 5Nzf + MxlVD0t5tzqzhniZ5BKZTtvCI6STbrFYnKcJwTyI   eaEDNtre5EaqEBbrYhlGTRxNmz2SdRi9Im9iCSw9pjDVDDJdzmhENhASmFQMeo7N   IS8AY3zJSjOQPKFymZrSa8hxWp88K1 / igxs12IhhpqNjMiUi29gH2T + QLPTDzwEq   EHTY1K6B0zlNuyp8HR5pNOqYymdnoSpCV3z0deTobAF7KiFYp2pXvoNo8Pc19Yl0   mQIDAQAB   ----- END PUBLIC KEY -----

加密密码为:

  

CgG33ytbS3CuK + rOpJRamQ6e8xCj7Q35m6YxWXc44r / D03VubXZO1f5 / zF7Zsc42UOOwqbYahApXBXL6o3J5MVu0cDkjstVoUnFJiPRHWmwq9AA0uvLC55gou + VzvmvRzFO38LMZ2BpsQLOjfv16LGWx7MLfKSVFGC8YVHgv6QlEbDFdd / HJDbqAKOoyQWlKXfVeMKmd8ORnq3 + B3Tmk57O3BHDVOlmezSgf + YN828u4ChZ08JzjgBo7MP2xCl6pLEeZxiFGjRwrTgRfLXQ7aMB / RyeMMHwInJiTS3 / M2Mez8C3 / +杂志/ DIfrLDA9LVdRYdy2n4AxbtyrLTun4mjDO + pYS3HqZlGn2MW5Orc9VH + 1CPn2omLVj / qqa6tIoFuJOdpxn / Y9

感谢您的光临。 问候。

1 个答案:

答案 0 :(得分:0)

如果您的.PEM文件显示“BEGIN PUBLIC KEY”,那么它可能是X.509 SubjectPublicKeyInfo结构。这意味着它看起来像

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)

这是DER编码的blob。每个xx值表示一个长度,可以超过一个字节。

因此,当您加载此密钥时,您将获取所有开销/结构内容,以及模数字节和指数字节,并调用所有模数。因此,实际效果是您使用与解密时不同的公钥进行加密。

.NET不能轻松阅读PEM密钥内容。最好的办法是将此密钥转换为证书。如果您还没有证书,可以openssl req -x509 -new -key theprivatekey.pem -out selfsignedcert.cer(并根据主题提示回答您喜欢的任何内容)。

否则,您现在已缩减为How to load the RSA public key from file in C#(以及其他相关问题)。