2016-07-27 50 views
1

我一直在研究一個算法來執行暴力破解。它更多的是個人利益而不是任何惡意使用tbh。我一直對密碼學和安全感興趣。 我在應用程序上有一個模式,它將創建工作線程以對給定長度(每個線程長度爲1個線程)行使可能的組合。例如:你開始的過程 - 然後它將以長度1,2,3,4,5,6,7,8等開始。 隨着長度較低的線程完成,它會將可疑密碼長度增加1併產生一個新線程。 限制因素是ProcessorCount -1(爲了避免線程鎖定或GUI線程被凍結:通常發現系統在空閒內核時更穩定)C#暴力 - 多線程固定長度的密碼

因此,在4核心系統上,您將使用密碼長度1- 3,當1,2和3完成後,它將移動到4,5,6等等。 長度1-5幾乎立即完成。在3-4秒內6-7。 長度8需要30-45秒。 (這些時間取決於它是數字/字母等) 更多可能的字符增加了我們需要檢查的密鑰空間。

好的,這是多線程的一種方法。 但我想介紹的另一種方法是更復雜一點。 它涉及使用多個線程來行使固定懷疑長度密碼的完整密鑰空間。例如:我們知道它的長度是8位數,所以使用我們所有的線程來更快地獲得8位密碼密鑰空間。

我不確定如何繼續。

如: 讓我們想象我們的密碼是100 我們有自己的處理器 8個內核所以這是7 - 如果我們與我-1辦法去潛在的線程(1000組合?)。 這可以解決大約143個組合來測試每個線程。 我只是想知道如何有效地計算每個線程的起始位置。

例如:

線索1將與000,並在142 線程2端開始在285等與143和端將開始

這聽起來很容易用數字,但是當使用的陣列的可能的字符 - 'abcdefghijklmnopqrstuvwxyz1234567890'
如何計算出開始點和結束點? 該字符串中包含36個可能的字符。 3個字母的密碼是36 x 36 x 36 = 46656個字符組合嗎?

好吧,如果我有7個線程在每個6666組合上工作。 如何獲取這些開始和結束位置並將它們轉換爲比較字符串。

我想我的主要問題是這個: 如何將組合索引變成由可用字符構造的字符串?

如:

  • 1可能會是 'A'
  • 2將 'B'
  • 37很可能是 'AB' 等
+0

你看過這個嗎? https://msdn.microsoft.com/en-us/library/ff963552.aspx – 1615903

+0

如果'a'是可能性,並且蠻力計算尋找3個字符長的密碼,它將需要''(一個開放空間)在你可能的人物列表中,否則它永遠不會到達那裏。它會以'aaa'開頭,另一個問題是如果你將它添加到你的列表中,那麼可能的密碼可能是'a'和'a',所以你需要考慮這個 – Neil

+0

是的,可能的K字母詞的數量有n個符號是n^k。例如,有10個十進制數字,可能的3位數字的數量是... 10^3。甚至在獲得10個字符的密碼之前,你的蠻力方法將需要一段時間。 36^7是78億美元而變化。 –

回答

0

不會建議您在這樣做,但如果這是你想要的方式,然後想想這樣

你有36個可能性字符1和36上c對於字符1中的每個可能性,都是字符2。對於字符3也是一樣。
所以。 。 。
採取的第一個字符的可能性和devide由6(線程)(7會亂碼)
給你6每線程
那麼這是6個不同的具有36X36 possibities

這意味着螺紋1個字符1的possibilites完成所有那些與A,b,C,d,e和f
線程2然後將做G,H,I,J,K和L

0

相反開始具有各自的正確的線索搜索1/n t h的搜索空間,考慮將其切分成「邏輯」片段(即,這是有意義的)。這意味着你將創建比核心更多的工作,並且每個線程完成前一個工作後就可以完成其中一個工作。

E.g.對於數字8位密碼,您可以創建任務0至9,其中任務n是「搜索所有以數字n開頭的8位密碼」。對於字母數字密碼,您可以創建36個任務:「搜索以'a'開始的所有密碼」,「...以'b'開始,...,」以'0'開始「。

將所有任務放入池中,根據需要啓動儘可能多的線程,併爲其提供池中的任務。任務完成後,讓線程從池中接受新任務,直到耗盡。

你可以使用這個Thread Pool,但坦率地說,我只想創造一個簡單的機制,我自己,在那裏工作的池是一個List<Action>,並使用一個簡單的lock荷蘭國際集團的機制來拉動任務從名單一旦前面的動作完成。


編輯:颳起了一個簡單的例子。它看起來像很多代碼,但它非常簡單。沒有真正的測試,但應該給你一個線索我的意思。

private List<Action> jobs = new List<Action>(); 
private object jobsLock = new object(); 

// This is the CPU-intensive function that does the actual work of checking passwords 
private void TestPasswords(int length) { 
    for(int i = 0; i < (1 << length); i++) 
    { 
     // Simulate testing the password. 
     Thread.Sleep(100); 
    } 
} 

// Each thread is dispatched with this action. 
// It keeps pulling jobs from the queue and executing them until no more remain. 
private void DoWork() 
{ 
    while(true) 
    { 
     Action job = null; 
     lock(this.jobsLock) 
     { 
      if(this.jobs.Count == 0) 
      { 
       return; 
      } 

      job = this.jobs[0]; 
      this.jobs.RemoveAt(0); 
     } 

     if(job != null) 
     { 
      job(); 
     } 
    } 
} 

// Tester method 
public void Run() 
{ 
    // For all password lengths from 1 to 8, generate a job to test passwords. 
    // You probably want to divide these differently (e.g. let i be the job that tests 
    // all 1 - 8 character passwords starting with the character i, such that 
    // all jobs are approximately of equal length). 
    for(int i = 1; i <= 8; i++) 
    { 
     int length = i; 
     this.jobs.Add(() => TestPasswords(length)); 
    } 

    // Create a background thread for each of the cores except one, 
    // and let them execute the DoWork loop until the queue is empty. 
    // You may build a ContinueWith or WaitAll mechanism to catch the results 
    // and build some callback stuff to get the progress. 
    int numberOfCores = 8; 
    for(int i = 0; i < numberOfCores - 1; i++) 
    { 
     Task.Run(DoWork); 
    } 
}