简体   繁体   English

将PHP密码解密转换为C#

[英]Convert PHP cipher decryption to C#

I have inherited some C# code where a PHP page containing the function &decrypt was compiled/transformed into a standalone Windows EXE. 我继承了一些C#代码,其中包含功能&decrypt的PHP页面被编译/转换为独立的Windows EXE。 I am wanting to take this PHP code and put the functionality into C#. 我想使用此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;
}

I have found a couple a questions that referred to this code, but did not provide much insight: Just want to decode the code into plain text and "MD5 decrypt" php function to MySQL stored function 我发现了几个与该代码有关的问题,但并没有提供太多的见解: 只是想将代码解码为纯文本,并将“ PHP解密” PHP函数转换为MySQL存储函数

Helpful links: PHP base64_decode C# equivalent 有用的链接: PHP base64_decode C#等效项

http://nuronconsulting.com/c-pack-h.aspx http://nuronconsulting.com/c-pack-h.aspx

I can get correct results except for the 2nd and 3rd to last characters. 除了第2个和第3个字符之外,我都能得到正确的结果。 I think my base64 decode is still off. 我认为我的base64解码仍然无效。

Edit: Updated to latest code being used. 编辑:更新为正在使用的最新代码。 Removed intermediate edits. 删除了中间编辑。

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

The code is not complete in the loop (hence the commented out code), however, the question I posed is answered. 该代码在循环中不完整(因此注释掉了代码),但是,我提出的问题得到了回答。 The encoding, the XOR issue, the php pack replication is accomplished via helpful links that are in the question. 编码,XOR问题,php pack复制是通过问题中的有用链接来完成的。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM