2016-07-27 77 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); 
    } 
}