Reputation: 321
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();
}
Upvotes: 0
Views: 165
Reputation: 93948
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.
Upvotes: 1