我继承了一些C#代码,其中包含函数& decrypt的PHP页面被编译/转换为独立的Windows EXE。我想要使用这个PHP代码并将功能放入C#。
function &decrypt($enc_text, $password)
{
$iv_len = 16;
$enc_text = base64_decode($enc_text);
$i = $iv_len;
$n = strlen($enc_text);
$plain_text = '';
$iv = substr($password ^ substr($enc_text, 0, $iv_len), 0, 512);
while ($i < $n)
{
$block = substr($enc_text, $i, 16);
$plain_text .= $block ^ pack('H*', md5($iv));
$iv = substr($block . $iv, 0, 512) ^ $password;
$i += 16;
}
return $plain_text;
}
我发现了一些涉及此代码的问题,但没有提供太多见解: Just want to decode the code into plain text 和"MD5 decrypt" php function to MySQL stored function
有用的链接: PHP base64_decode C# equivalent
http://nuronconsulting.com/c-pack-h.aspx
除了第2个和第3个到最后一个字符外,我可以得到正确的结果。我认为我的base64解码仍然关闭。
编辑:已更新为正在使用的最新代码。删除了中间编辑。
private string decipher(string ienc_text, string ipassword)
{
int iv_len = 16;
byte[] toEncryptArray = Convert.FromBase64String(ienc_text);
string encryptedStringx = System.Text.Encoding.Default.GetString(toEncryptArray);
string encryptedString = Encoding.GetEncoding(28591).GetString(toEncryptArray);
string password = ipassword;
int i = iv_len;
int n = encryptedString.Length;
string plain_text = "";
string iv = phpXOR(ipassword, encryptedString.Substring(0, iv_len));
while (i < n)
{
string block = encryptedString.Substring(i, iv_len);
string md5 = getMD5(iv);
byte[] testPack = PackH(md5);
string testPackstring = Encoding.Default.GetString(testPack);
string tmp = phpXOR(block, testPackstring);
plain_text += tmp;
string block_iv = block + iv;
string tmp_iv = block_iv;
if (block_iv.Length > 512)
{
tmp_iv = block_iv.Substring(0, 512);
}
iv = phpXOR(tmp_iv, password);
i += 16;
}
return plain_text;
}
public static byte[] PackH(string hex)
{
if ((hex.Length % 2) == 1) hex += '0';
byte[] bytes = new byte[hex.Length / 2];
for (int i = 0; i < hex.Length; i += 2)
{
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
return bytes;
}
string phpXOR(string text, string key)
{
byte[] result = new byte[key.Length];
for (int c = 0; c < key.Length; c++)
result[c] = (byte)(((byte)text[c]) ^ ((byte)key[c]));
return Encoding.Default.GetString(result);
}
public static string getMD5(string iValue)
{
byte[] textBytes = System.Text.Encoding.Default.GetBytes(iValue);
//byte[] textBytes = System.Text.Encoding.GetEncoding(28591).GetBytes(password);
try
{
System.Security.Cryptography.MD5CryptoServiceProvider cryptHandler;
cryptHandler = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] hash = cryptHandler.ComputeHash(textBytes);
string ret = "";
foreach (byte a in hash)
{
if (a < 16)
ret += "0" + a.ToString("x");
else
ret += a.ToString("x");
}
return ret;
}
catch
{
throw;
}
}
答案 0 :(得分:0)
代码在循环中没有完成(因此注释掉了代码),然而,我提出的问题得到了回答。编码,XOR问题,php包复制是通过问题中的有用链接完成的。
private string decipher(string ienc_text, string ipassword)
{
int iv_len = 16;
byte[] toEncryptArray = Convert.FromBase64String(ienc_text);
string encryptedString = Encoding.GetEncoding("iso-8859-1").GetString(toEncryptArray);
string password = ipassword;
int i = iv_len;
int n = encryptedString.Length;
string plain_text = "";
string iv = phpXOR(ipassword, encryptedString.Substring(0, iv_len));
while (i < n)
{
string block = encryptedString.Substring(i, iv_len);
string md5 = getMD5(iv);
byte[] testPack = PackH(md5);
string testPackstring = Encoding.GetEncoding("iso-8859-1").GetString(testPack);
string tmp = phpXOR(block, testPackstring);
plain_text += tmp;
//string block_iv = block + iv;
//string tmp_iv = block_iv;
//if (block_iv.Length > 512)
//{
// tmp_iv = block_iv.Substring(0, 512);
//}
//iv = phpXOR(tmp_iv, password);
//i += 16;
}
return plain_text;
}
public static byte[] PackH(string hex)
{
if ((hex.Length % 2) == 1) hex += '0';
byte[] bytes = new byte[hex.Length / 2];
for (int i = 0; i < hex.Length; i += 2)
{
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
return bytes;
}
string phpXOR(string text, string key)
{
byte[] result = new byte[key.Length];
for (int c = 0; c < key.Length; c++)
result[c] = (byte)(((byte)text[c]) ^ ((byte)key[c]));
return Encoding.Default.GetString(result);
}
public static string getMD5(string iValue)
{
byte[] textBytes = System.Text.Encoding.Default.GetBytes(iValue);
try
{
System.Security.Cryptography.MD5CryptoServiceProvider cryptHandler;
cryptHandler = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] hash = cryptHandler.ComputeHash(textBytes);
string ret = "";
foreach (byte a in hash)
{
if (a < 16)
ret += "0" + a.ToString("x");
else
ret += a.ToString("x");
}
return ret;
}
catch
{
throw;
}
}