为什么我的蛮力MD5黑客无法正常工作?

时间:2015-01-24 17:27:39

标签: c++ md5 brute-force

对于类,我获得了通过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;
}

不,我实际上并不知道计数的最终值是什么。我最初将它作为一个int而不是一个long,所以在运行9个小时后它溢出了。在我再次运行它并得到一个新号码之前,我想和你们一起检查一下。

1 个答案:

答案 0 :(得分:4)

除了样式问题,

                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。你有很多代码重复(例如,使用不同的变量进行几乎/完全相同的操作)这意味着你可以轻松地重构为递归函数或堆栈(push / pop to heap style)循环并实现更易于阅读(因此通常不易出错)代码。

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