为什么我的蛮力 MD5 hack 不起作用?

Why is my brute-force MD5 hack not working?

对于 class,我通过 md5 哈希获得了一个 运行 的密码。有人告诉我最多 6 个字符,只能包含大写字母和数字。我要写一个蛮力算法来揭示原始密码。我已经能够通过我的程序获得我自己的哈希值,运行,并对其进行解码,但是在我老师给我们的那个上它失败了。我从一个网站获取了我的 md5,并与其他人核对了结果,所以我知道这不是问题所在。我的代码是否有错误,比如我没有涵盖所有可能的组合,或者给我的哈希值很可能有错误?

#include <stdlib.h>
#include <string>
#include <iostream>
#include "md5.h"//File was sourced from http://www.zedwood.com/article/cpp-md5-function

using namespace std;

const int numPossibleChar = 36;
const string givenHash = "ad2ad129385e4b2ba3b477378bc1d9b6";
long count=0;//make sure I go through all combinations

const char * charOptions[numPossibleChar]={"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
                            "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
                            "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7",
                            "8", "9", "0"};



int main()
{   
    for( int i =0; i<numPossibleChar; i++)
    {
         string guess1 = charOptions[i];
        string guessHash = md5(guess1);
        if( md5(guess1)==givenHash)
        {
            cout <<"match, password is: "<< guess1<<endl;
            return 0;
        }
        cout<<guess1<<endl;
        count++;
        for (int j=0; j<numPossibleChar; j++)
        {
            string guess2=guess1+charOptions[j];
            if( md5(guess2)==givenHash)
            {
                cout <<"match, password is: "<< guess2<<endl;
                return 0;
            }
            count++;
            for(int k=0; k<numPossibleChar; k++)
            {
                string guess3=guess2+charOptions[k];
                if( md5(guess3)== givenHash)
                {
                    cout <<"match, password is: "<< guess3<<endl;
                    return 0;
                }
                count++;
                for(int l=0; l<numPossibleChar; l++)
                {
                    string guess4=guess3+charOptions[l];
                    if( md5(guess4)== givenHash)
                    {
                        cout <<"match, password is: "<< guess4<<endl;
                        return 0;
                    }
                    count++;
                    for(int m=0; m<numPossibleChar; m++)
                    {
                        string guess5=guess4+charOptions[m];
                        if( md5(guess4)==givenHash)
                        {
                            cout <<"match, password is: "<< guess5<<endl;
                            return 0;
                        }
                        count++;
                        for(int n=0; n<numPossibleChar; n++)
                        {
                            string guess6=guess5+charOptions[n];
                            if( md5(guess6)==givenHash)
                            {
                                cout <<"match, password is: "<< guess6<<endl;
                                return 0;
                            }
                            count++;
                        }
                    }
                }

            }
        }
    }

    cout << "Count "<<count<<endl;




    return 0;
}

不,我实际上不知道 count 的最终值是多少。我最初将它作为 int 而不是 long,所以在 运行ning 9 小时后它溢出了。在我再次 运行 并获得新号码之前,我想和你们核实一下。

抛开风格问题,

                string guess4=guess3+charOptions[l];
                if( md5(guess4)== givenHash)
                {
                    cout <<"match, password is: "<< guess4<<endl;
                    return 0;
                }
                count++;
                for(int m=0; m<numPossibleChar; m++)
                {
                    string guess5=guess4+charOptions[m];
                    if( md5(guess4)==givenHash)
                    {
                        cout <<"match, password is: "<< guess5<<endl;
                        return 0;
                    }

我敢猜测您并不是要检查 md5(guess4) 两次。

编辑,以扩展此问题和样式问题: 显然,如果不检查 md5(guess5),六分之一的潜在密码将被遗漏。

通过重构您的代码以获得更好的风格,可以通过简单的方法解决此类错误。特别要注意的是,我建议您阅读 Arrow Anti-pattern。您有很多代码重复(例如,使用不同的变量执行 nearly/exact 相同的操作),这意味着您可以轻松地重构为递归函数或堆叠(push/pop 堆样式)循环并更容易实现- 阅读(因此 通常 不易出错)代码。

如果您花了 9 个小时才使 count 溢出,我建议您遇到了一些性能问题(假设您 运行 使用的是相对较新的硬件)。您可以进一步扩展它,通过为每次检查重复使用现有字符串来减少字符串分配和释放的数量。例如,count 可以通过添加 count=1+i+j+k+l+m+n 来严格推断,因此没有必要手动增加它。