2015-01-24 2 views
3

Для класса мне был предоставлен пароль, который запускался через хэш хд5. Мне говорят, что это максимум 6 символов, в верхнем регистре и только цифры. Я должен написать алгоритм грубой силы, чтобы открыть исходный пароль. Я смог получить свои собственные значения хэша, запустить его через свою программу и декодировать его, но это не удается на том, что дал нам мой учитель. Я получил мой md5 с веб-сайта и проверил его результаты против других, поэтому я знаю, что это не проблема. Есть ли какая-то ошибка в моем коде, например, я не охватываю все возможные комбинации, или, скорее всего, ошибка в хэш-значении, предоставленная мне?Почему мой грубой взлом 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; 
} 

И нет, на самом деле у меня нет окончательного значения. Я intially имеет его как int вместо длинного, поэтому после запуска 9 часов он переполнен. Я хотел проверить с вами, ребята, прежде чем снова запустить его и получить новый номер.

+1

Является ли хэш в исходном коде тем, который вам дал? Если нет, то что вам дали? –

+0

Вам нужно сделать так много распределений строк? Вы можете собрать строки-кандидаты в буфере символов в MD5 и сравнить результат как байты без преобразования в шестую строку для сравнения. (Я не знаю, является ли это значительным по времени вычисления MD5, но кажется излишним.) – Rup

+0

Я бы проверил, что основной алгоритм работает первым, прежде чем добавлять часть «md5» (md5 - довольно медленная операция во всей схеме вещей). И используйте короткий пароль, например. 3 буквы и убедитесь, что вы можете найти совпадение. Например, «X9Z». Для каждого добавочного персонажа, который вы добавляете, это займет 36 раз дольше, поэтому пара дополнительных символов будет длиться от нескольких минут до нескольких часов, что затрудняет решение проблемы. –

ответ

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, поэтому нет необходимости увеличивать его вручную.

+1

О, боже мой, я думаю, что это возможно. Надеюсь, что так! Спасибо. Я снова запускаю его, а затем принимаю ваш ответ. – art3m1sm00n

+1

Значит, проблема? – inetknght