0

我花了一整天的时间寻找解决问题的方法,最后决定发帖寻求帮助。我真的不知道这是否是发布此内容的最佳地点,但也许有人可以帮助我。

所以我试图在 C# 中创建一个简单的登录表单,一切都可以从数据库中获取用户名、MD5(密码)和盐。现在我的问题是如何从我的表单输入的密码+盐进行比较。我不知道当用户在论坛上创建帐户时 vbulleting 如何存储密码,也不知道他如何生成盐,如果它是随机的,或者用户名基础,以及他进行了多少次迭代。

谁能帮我?

编辑: -

$vbulletin->userinfo['password'] != iif($password AND !$md5password, md5(md5($password) . $vbulletin->userinfo['salt']), '') AND
            $vbulletin->userinfo['password'] != iif($md5password, md5($md5password . $vbulletin->userinfo['salt']), '') AND
            $vbulletin->userinfo['password'] != iif($md5password_utf, md5($md5password_utf . $vbulletin->userinfo['salt']), '')

发现了,但仍然不知道他们是如何做到的,所以我可以尝试在 C# 中重现它

最好的问候,玛格

4

2 回答 2

0

给定代码,格式化(忽略这可能会破坏语法):

    $vbulletin->userinfo['password'] != iif($password AND !$md5password,
        md5(md5($password) . $vbulletin->userinfo['salt']), '')
AND $vbulletin->userinfo['password'] != iif($md5password,
        md5($md5password . $vbulletin->userinfo['salt']), '')
AND $vbulletin->userinfo['password'] != iif($md5password_utf,
        md5($md5password_utf . $vbulletin->userinfo['salt']), '')

这个表达式检测到“所有方法的失败”,但是因为我觉得这很难阅读,让我们通过应用 De Morgan 的隐式外部否定将它重写为“任何方法的成功”的正匹配:

    $vbulletin->userinfo['password'] == iif($password AND !$md5password,
        md5(md5($password) . $vbulletin->userinfo['salt']), '')
OR  $vbulletin->userinfo['password'] == iif($md5password,
        md5($md5password . $vbulletin->userinfo['salt']), '')
OR  $vbulletin->userinfo['password'] == iif($md5password_utf,
        md5($md5password_utf . $vbulletin->userinfo['salt']), '')

现在,应用简化和注释,iff(x,y,z)就像x?y:z我们最终在 C# 中得到类似以下内容一样:

   storedPW == password && !md5password ? md5(md5(password) + salt) : ''
|| storedPW == md5password ? md5(md5password + salt) : ''
|| storedPw == md5password_utf ? md5(md5password_utf + salt) : ''

检查有点难看,但..不是我的代码。要实现的重要一点是模式是:

 md5(md5(password) + salt) -> storedPw

不幸的是,这应该与 insidepro 链接匹配md5(md5($pass).$salt)- 使用该工具时,请确保您提供的是纯文本密码,而不是数据库中的哈希。

YMMV。

于 2013-06-30T01:50:03.473 回答
0

所以这是我的问题的解决方案,最后我设法让它工作。

问题是 C# 使用所有字符串作为 unicode,而 vbulletin 使用所有字符串作为 UTF8

为了测试,我创建了一个新表单,添加了一个新文本框和一个按钮。这无论如何都不会连接到数据库,我提供了直接从数据库中获取的盐。(为了测试)

由于已经说明 vbulleting 登录如下: md5(md5(password)+salt)

因此,要在 C# 中重现相同但使用 UTF8 的解决方案是:

static public string GetMd5Sum(string str)
    {
        //vBulletin uses UTF8 as strings, so you need to pass the user input string as UTF8 also
        Encoder enc = System.Text.Encoding.UTF8.GetEncoder();

        //Create a byte[] array to store the new UTF8 string
        byte[] utf8text = new byte[str.Length];

        //Pass the string to the byte[] array
        enc.GetBytes(str.ToCharArray(), 0, str.Length, utf8text , 0, true);

        //Hash the byte[] array with our UTF8 string inside
        MD5 md5 = new MD5CryptoServiceProvider();
        byte[] result = md5.ComputeHash(utf8text);

        //Build the final string by converting each byte
        //into hex and appending it to a StringBuilder
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < result.Length; i++)
        {
            sb.Append(result[i].ToString("x2")); //x2 here so the outcome result is all in lowercase, couse vbulleting also stores all in lowercase
        }

        //And return it
        return sb.ToString();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        //Get the user input password as plain text
        string pass = textBox1.Text;

        //Here i provided the salt explicit that i took from the database
        string salt = "N1GOt=>8sdO@E54)PH2@NCm5yI#]3u";

        //Here we convert the plain text password into the first hash
        string p1 = GetMd5Sum(pass);

        //Here we add the salt to the previous hashed password
        string p2 = p1 + salt;

        //Here we hash again the previous hashed password + the salt string
        string final = GetMd5Sum(p2);

        //this was just to the test to see if it all works as intended
        MessageBox.Show(final);
    }

这将输出存储在数据库中的完全相同的哈希作为密码。

感谢 user2246647 在我遇到的这个问题上提供的所有帮助。

于 2013-06-30T15:15:39.467 回答