将AES解密从PHP转换为C#

马特

我正在尝试将一些有效的php代码转换为c#以便进行AES解密。

可用的PHP代码:

function convert_from_hex($h) {
    $r="";
    for ($i=0; $i<strlen($h); $i+=2) 
        if ((isset($h[$i])) && (isset($h[$i+1]))) 
            $r.=chr(hexdec($h[$i].$h[$i+1]));

    return $r;
}

function decryptAES($crypt_text, $key) {

    $crypt_text=convert_from_hex($crypt_text);                                              // convert from hex

    $iv = substr($crypt_text, 0, 16);                                                       // extract iv
    $crypt_text = substr($crypt_text, 16);                                                  // extract iv

    $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');                 // decrypt
    @mcrypt_generic_init($td, $key, $iv);
    $package = @mdecrypt_generic($td, $crypt_text);

    mcrypt_generic_deinit($td);                                                             // close encryption
    mcrypt_module_close($td);

    $padqty=ord($package[strlen($package)-1]);                                              // remove padding

    return substr($package, 0, strlen($package)-$padqty);
}

C#代码损坏:

public string test()
        {
            string data = ConvertHex("149B56B7240DCFBE75B7B8B9452121B0E202A18286D4E8108C52DBB2149D820B980FFC7157470B9573AA660B2FAAB158E321023922191BCEA5D6E1376ABE6474");

            string iv = data.Substring(0, 16);
            string toDecrypt = data.Substring(16);

            return AESEncryption.DecryptString(Encoding.Default.GetBytes(toDecrypt), Encoding.ASCII.GetBytes("C728DF944B666652"), Encoding.Default.GetBytes(iv));
        }

static public string DecryptString(byte[] cipherText, byte[] Key, byte[] IV)
        {
            // Check arguments. 
            if (cipherText == null || cipherText.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("Key");

            // Declare the string used to hold 
            // the decrypted text. 
            string plaintext = null;

            byte[] binaryDecryptedData;

            // Create an Aes object 
            // with the specified key and IV. 
            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Mode = CipherMode.CBC;
                aesAlg.Padding = PaddingMode.PKCS7;
                aesAlg.KeySize = 128;
                aesAlg.BlockSize = 128;
                aesAlg.Key = Key;
                aesAlg.IV = IV;

                // Create a decrytor to perform the stream transform.
                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);


                // Create the streams used for decryption. 
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (MemoryStream srDecrypt = new MemoryStream())
                        {
                            var buffer = new byte[1024];
                            var read = csDecrypt.Read(buffer, 0, buffer.Length);
                            while (read > 0)
                            {
                                srDecrypt.Write(buffer, 0, read);
                                read = csDecrypt.Read(buffer, 0, buffer.Length);
                            }
                            csDecrypt.Flush();
                            binaryDecryptedData = srDecrypt.ToArray();
                        }
                    }
                }

            }

            StringBuilder sb = new StringBuilder();
            foreach (byte b in binaryDecryptedData)
                sb.Append((char)b);
            plaintext = sb.ToString();

            return plaintext;
        }

        public string ConvertHex(String hexString)
        {
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < hexString.Length; i += 2)
            {
                string hs = hexString.Substring(i, 2);

                sb.Append((char)Convert.ToUInt32(hs, 16));
            }

            return sb.ToString();
        }

PHP代码的正确输出是:失败(1)不是有效的请求或命令。

C#代码的输出为:“ H,-§±uH¤¥±BÃrY” |¡JJѾà`ªx“äommand

我猜想我有某种编码问题,尽管我尝试了许多不同的选择都没有成功。这两个代码段均在Windows框上运行,因此我相信默认编码为Windows-1252。

任何建议,将不胜感激。

替换为ConvertHex,它修复了我的问题(由于猫头鹰的帮助)

public static byte[] StringToByteArray(string hex)
{
    return Enumerable.Range(0, hex.Length)
                     .Where(x => x % 2 == 0)
                     .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                     .ToArray();
}
马丁·波德维斯(Maarten Bodewes)

您正在使用字符串数据的前16个字节,而不是二进制数据的16个字节。这就是导致主要问题的原因。您需要首先将十六进制转换为字节,然后剥离前16个字节以用作IV。您的ConvertHex方法(未显示)已损坏,它应该返回一个字节数组。解密后的纯文本确实正确结尾的事实"ommand"清楚地表明了IV值有问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章