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