我正在尝试将一些有效的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();
}
您正在使用字符串数据的前16个字节,而不是二进制数据的16个字节。这就是导致主要问题的原因。您需要首先将十六进制转换为字节,然后剥离前16个字节以用作IV。您的ConvertHex
方法(未显示)已损坏,它应该返回一个字节数组。解密后的纯文本确实正确结尾的事实"ommand"
清楚地表明了IV值有问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句