c# RSA加密到PHP使用PHP OpenSSL公钥解密

本文关键字:PHP OpenSSL 公钥 解密 使用 加密 RSA | 更新日期: 2023-09-27 18:19:22

我试图通过nussoap从SOAP服务器加载OpenSSL公钥到c#,使用公钥加密我的数据,然后将数据发送回PHP服务器使用私钥解密。

我的c#是这样的:

static void Main(string[] args)
{
    PHPRef.AddService test = new PHPRef.AddService();
    var pkey = test.getPublicKey();
    //Console.WriteLine(pkey.ToString());
    byte[] PublicKey = GetBytes(pkey);
    //Values to store encrypted symmetric keys.
    byte[] EncryptedSymmetricKey;
    byte[] EncryptedSymmetricIV;
    //Create a new instance of RSACryptoServiceProvider.
    RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048);
    //Get an instance of RSAParameters from ExportParameters function.
    RSAParameters RSAKeyInfo = RSA.ExportParameters(false);
    //Set RSAKeyInfo to the public key values. 
    RSAKeyInfo.Modulus = PublicKey;
    //Import key parameters into RSA.
    RSA.ImportParameters(RSAKeyInfo);
    //Create a new instance of the RijndaelManaged class.
    RijndaelManaged RM = new RijndaelManaged();
    //Encrypt the symmetric key and IV.
    EncryptedSymmetricKey = RSA.Encrypt(RM.Key, false);
    EncryptedSymmetricIV = RSA.Encrypt(RM.IV, false);
    Console.WriteLine("RijndaelManaged Key and IV have been encrypted with RSACryptoServiceProvider.");
    byte[] encryptedData = RSA.Encrypt(GetBytes("password"), false);
    //byte[] returned = (byte[])(Array)test.getDecrypted((sbyte[])(Array)encryptedData);
    //string answer = GetString(returned);
    string answer = test.getDecrypted((sbyte[])(Array)encryptedData);
    Console.WriteLine(answer);
    Console.ReadLine();
}
static byte[] GetBytes(string str)
{
    byte[] bytes = Encoding.ASCII.GetBytes(str);
    return bytes;
}
static string GetString(byte[] bytes)
{
    char[] chars = Encoding.ASCII.GetChars(bytes);
    return new string(chars);
}

我的PHP是这样的:

function getPublicKey()
{
    $crt = file_get_contents("public.crt");
    // $publickey = str_ireplace("'r", "", $crt);
    // $publickey = str_ireplace("'n", "", $publickey);
    // $publickey = str_ireplace("-----BEGIN CERTIFICATE-----", "", $publickey);
    // $publickey = str_ireplace("-----END CERTIFICATE-----", "", $publickey);
    return $crt;
}
function getDecrypted($input)
{
    global $privateRSA;
    // $privateRSA = str_ireplace("'r", "", $privateRSA);
    // $privateRSA = str_ireplace("'n", "", $privateRSA);
    // $privateRSA = str_ireplace("-----BEGIN RSA PRIVATE KEY-----", "", $privateRSA);
    // $privateRSA = str_ireplace("-----END RSA PRIVATE KEY-----", "", $privateRSA);
    if(!openssl_private_decrypt($input, $decrypted, $privateRSA))
        return "fail";
    else
        return "success";
    return $decrypted;
}

不用说,我每次都得到"失败"。有什么建议吗?我试图用纯PHP和纯c#来做这件事,没有特殊的库。密钥为2048位

c# RSA加密到PHP使用PHP OpenSSL公钥解密

我花了将近一整天的时间去寻找,结果发现非常简单。你不需要BouncyCastle, SecLib,任何第三方库,什么都不需要。

c#:

static void Main(string[] args)
{
    PHPRef.AddService test = new PHPRef.AddService();
    var pkey = test.getPublicKey();
    byte[] pkeybyte = GetBytes(pkey);
    X509Certificate2 cert = new X509Certificate2();
    cert.Import(pkeybyte);
    RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PublicKey.Key;
    byte[] encryptedData = rsa.Encrypt(GetBytes("password"), false);
    Console.WriteLine(GetString(encryptedData));
    string answer = test.getDecrypted((sbyte[])(Array)encryptedData);
    Console.WriteLine(answer);
    Console.ReadLine();
}

和PHP:

像这样修改getPublicKey

function getPublicKey()
{
    $crt = file_get_contents("public.crt");
    $publickey = str_ireplace("'r", "", $crt);
    $publickey = str_ireplace("'n", "", $publickey);
    $publickey = str_ireplace("-----BEGIN CERTIFICATE-----", "", $publickey);
    $publickey = str_ireplace("-----END CERTIFICATE-----", "", $publickey);
    return $publickey;
}