donglu9825 2014-12-14 23:27
浏览 58
已采纳

将AES解密从php转换为c#

I'm attempting to convert some working php code to c# in order to do aes decryption.

Working PHP code:

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

Broken C# Code:

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

The correct output of the PHP code is: Fail (1) Not a valid Request or Command.

The output of the C# code is: ²H,-§±uH¤¥±BÃrY¡|¡JJѾà`ªx"äommand

I'm guessing that I have some sort of encoding issue, although I've tried many different options without success. Both code snippets are running on a windows box, so I believe the default encoding is windows-1252.

Any suggestions would be appreciated.

Replacement for ConvertHex which fixed my issues (thanks to owlstead's help)

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();
}
  • 写回答

1条回答 默认 最新

  • dsv17139 2014-12-14 23:44
    关注

    You are using the first 16 bytes of string data instead of 16 bytes of binary data. This is what is causing the main issue. You need first to convert hex to bytes and then strip off the first 16 bytes to use as IV. Your ConvertHex method (not shown) is broken, it should return a byte array. The fact that your decrypted plaintext does end correctly with "ommand" clearly indicates a problem with the IV value.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 宇视监控服务器无法登录
  • ¥15 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥15 DruidDataSource一直closing
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
  • ¥50 STM32单片机传感器读取错误
  • ¥50 power BI 从Mysql服务器导入数据,但连接进去后显示表无数据