【问题标题】:C# encrypt PHP decrypt using RSAC# 使用 RSA 加密 PHP 解密
【发布时间】:2013-04-03 15:43:17
【问题描述】:

我正在尝试在 C# 和 PHP 之间构建一个简单的 RSA 加密解密过程。 我已经使用 phpseclib(http://phpseclib.sourceforge.net/) 完成了 PHP 中的加密和 C# 中的 decrpyt。但是我得到 “第 2103 行 C:\xampp\htdocs\Crypt\RSA.php 中的解密错误”这是这部分:

if ($lHash != $lHash2) {
        user_error('Decryption error', E_USER_NOTICE);
        return false;
    }

C#中的加密我用了这串代码:

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();

和我的基本 PHP 代码来 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);

我已经尝试过 PKC1 它还在 Crypt/RSA.php 中给出了另一个错误

【问题讨论】:

标签: c# php rsa phpseclib


【解决方案1】:

是的,我自己找到了解决方案。我更改了加密行:

byte[] bytes = Encoding.UTF32.GetBytes(inputString);  ==> byte[] bytes = Encoding.Default.GetBytes(inputString);

正如@Ryan 所说:

$ciphertext = base64_decode(strrev($ciphertext));  ==> $ciphertext = strrev(base64_decode($ciphertext));

感谢您的尝试。

【讨论】:

    【解决方案2】:

    既然您在 C# 中使用 Array.Reverse,我可能会猜测 PHP 中的 strrev 是不必要的。

    另外,phpseclib 的 Crypt_RSA 没有loadKeyfromXML。你从哪里得到的?做$rsa-&gt;loadKey() 就足够了。

    最后,我的猜测是 PKCS1 是必需的。使用时遇到什么错误?

    【讨论】:

    • 是的 $rsa->loadKey() 也可以工作,但没有任何区别。对于 PKCS,正如我评论的那样,不幸的是它给出了同样的错误
    • 你试过没有strrev吗?
    • 是的,我也尝试过使用/out strrev 和 base64_decode。仍然在 RSA.php 的同一行出现错误 另外,当我使用 PKCS1 时,我在行出现错误: if (ord($em[0]) != 0 || ord($em[1]) > 2) { user_error('解密错误', E_USER_NOTICE);返回假; }
    【解决方案3】:

    在我看来,在 PHP 中,您正在获取 Base64 编码的密文,将其反转,然后尝试对其进行 Base64 解码?我认为您想先对其进行解码,然后再反转结果。它们不是一回事。

    首先是否有必要进行这种逆转,我不能说。

    【讨论】:

    • 是的,我只是从源代码中获取代码,这就是为什么使用反转。对于从 php 加密并在 C# 中解密的 base64 效果很好,我使用了相同的操作
    • 先尝试解码,然后 strrev with(out) PKCS1 在没有 PKCS1 的情况下仍然在同一行给出错误,而使用 PKCS1 它在以下位置给出错误:'if (ord($em[0]) != 0 || ord($em[1]) > 2)'.
    【解决方案4】:

    我不得不说我没有完全理解你的问题,但它似乎是如何在 C# 和 PHP 中结合 RSA 加密。这样做我也遇到了一些麻烦,对于仍然感兴趣的每个人,我编写了一个工作项目,C# 程序和 PHP 脚本都创建 RSA 密钥并交换它们,然后加密通信(参见here)。

    【讨论】:

      猜你喜欢
      • 2015-03-16
      • 2013-03-17
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2012-11-27
      • 1970-01-01
      • 2013-04-22
      相关资源
      最近更新 更多