简体   繁体   English

C#中的PHP MCRYPT_RIJNDAEL_128加密

[英]PHP MCRYPT_RIJNDAEL_128 encryption in C#

I'm trying to rewrite this function in C#. 我正在尝试用C#重写这个函数。 but the C# output mismatches the php 但是C#输出与php不匹配

PHP version PHP版本

// Encrypt data using AES128-cbc
function encrypt($data, $key, $iv) {
    $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'cbc', '');
    mcrypt_generic_init($cipher, $key, $iv);
    $multipass = mcrypt_generic($cipher, $data);
    mcrypt_generic_deinit($cipher);
    return $multipass;
}

C# Version C#版本

public static string encrypt(string encryptionString, string iv, string key)
{
    byte[] clearTextBytes = Encoding.UTF8.GetBytes(encryptionString);
    var rijn = SymmetricAlgorithm.Create();
    rijn.KeySize = 128;
    rijn.Mode = CipherMode.CBC;
    var ms = new MemoryStream();
    var cs = new CryptoStream(ms, rijn.CreateEncryptor(Encoding.UTF8.GetBytes(key), Encoding.UTF8.GetBytes(iv)), CryptoStreamMode.Write);
    cs.Write(clearTextBytes, 0, clearTextBytes.Length);
    cs.Close();
    var tmp = Encoding.UTF8.GetString(ms.ToArray());
    return tmp;
}

Encrypt/Decrypt using PHP: 使用PHP加密/解密:

class Cipher {
    private $key, $iv;
    function __construct() {
        $this->key = "edrtjfjfjlldldld";
        $this->iv = "56666852251557009888889955123458";
    }
    function encrypt($text) {

        $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
        $padding = $block - (strlen($text) % $block);
        $text .= str_repeat(chr($padding), $padding);
        $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->key, $text, MCRYPT_MODE_CBC, $this->iv);

        return base64_encode($crypttext);
    }

    function decrypt($input) {
        $dectext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->key, base64_decode($input), MCRYPT_MODE_CBC, $this->iv);
        return $dectext;
    }
}

Encrypt/Decrypt using C#: 使用C#加密/解密:

public class RijndaelSimple
    {
        const string iv = "56666852251557009888889955123458";
        const string key = "edrtjfjfjlldldld";

        static public String EncryptRJ256(string plainText)
        {
            var encoding = new UTF8Encoding();
            var Key = encoding.GetBytes(key);
            var IV = encoding.GetBytes(iv);
            byte[] encrypted;

            using (var rj = new RijndaelManaged())
            {
                try
                {
                    rj.Padding = PaddingMode.PKCS7;
                    rj.Mode = CipherMode.CBC;
                    rj.KeySize = 256;
                    rj.BlockSize = 256;
                    rj.Key = Key;
                    rj.IV = IV;

                    var ms = new MemoryStream();

                    using (var cs = new CryptoStream(ms, rj.CreateEncryptor(Key, IV), CryptoStreamMode.Write))
                    {
                        using (var sr = new StreamWriter(cs))
                        {
                            sr.Write(plainText);
                            sr.Flush();
                            cs.FlushFinalBlock();
                        }
                        encrypted = ms.ToArray();
                    }
                }
                finally
                {
                    rj.Clear();
                }
            }

            return Convert.ToBase64String(encrypted);
        }

        static public String DecryptRJ256(string input)
        {
            byte[] cypher = Convert.FromBase64String(input);

            var sRet = "";

            var encoding = new UTF8Encoding();
            var Key = encoding.GetBytes(key);
            var IV = encoding.GetBytes(iv);

            using (var rj = new RijndaelManaged())
            {
                try
                {
                    rj.Padding = PaddingMode.PKCS7;
                    rj.Mode = CipherMode.CBC;
                    rj.KeySize = 256;
                    rj.BlockSize = 256;
                    rj.Key = Key;
                    rj.IV = IV;
                    var ms = new MemoryStream(cypher);

                    using (var cs = new CryptoStream(ms, rj.CreateDecryptor(Key, IV), CryptoStreamMode.Read))
                    {
                        using (var sr = new StreamReader(cs))
                        {
                            sRet = sr.ReadLine();
                        }
                    }
                }
                finally
                {
                    rj.Clear();
                }
            }

            return sRet;
        }

    }

Two issues with your C# code. 您的C#代码有两个问题。

  1. You should not be encoding the contents of your MemoryStream to UTF8. 您不应该将MemoryStream的内容编码为UTF8。 The output of the CryptoStream is binary and will not convert properly. CryptoStream的输出是二进制的,无法正确转换。 Either return a byte[] , or if you really want a string, encode the output to Hex or Base64. 要么返回一个byte[] ,要么你真的想要一个字符串,将输出编码为Hex或Base64。

  2. You need to set the padding mode via rijn.Padding = PaddingMode.Zeros; 您需要通过rijn.Padding = PaddingMode.Zeros;设置填充模式rijn.Padding = PaddingMode.Zeros; . Although it's not clearly stated, PHP pads data up to the block size using 0's. 虽然没有明确说明,PHP使用0来填充数据块大小。 The default for padding for SymmetricAlgorithm is PKCS7. SymmetricAlgorithm填充的默认值是PKCS7。

Also note that the signatures of your PHP and C# methods are different. 另请注意,PHP和C#方法的签名是不同的。 The parameter order for your PHP function is data, key, iv while the C# method is data, iv, key . PHP函数的参数顺序是data, key, iv而C#方法是data, iv, key If you're still having an issue after the changes I've listed above, it may be that your IV and key are reversed when calling your C# encrypt method. 如果您在上面列出的更改后仍然遇到问题,那么在调用C#encrypt方法时可能会反转您的IV和密钥。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM