C#Bruteforce-多线程处理固定长度密码

C#Bruteforce-多线程处理固定长度密码,c#,multithreading,passwords,brute-force,C#,Multithreading,Passwords,Brute Force,我一直在研究一种算法来进行暴力强迫。与其说是恶意使用tbh,不如说是出于个人利益。我一直对密码学和安全感兴趣。 我在应用程序上有一个模式,它将创建工作线程,以针对给定长度(每长度1个线程)执行可能的组合 你开始这个过程,然后它将以长度1、2、3、4、5、6、7、8开始,依此类推。 当长度较低的线程完成时,它会将可疑密码长度增加1,并生成一个新线程。 限制因素是ProcessorCount-1(为了避免线程锁定或GUI线程冻结:通常发现系统在有空闲内核的情况下更稳定) 因此,在4核系统上,您将处理

我一直在研究一种算法来进行暴力强迫。与其说是恶意使用tbh,不如说是出于个人利益。我一直对密码学和安全感兴趣。 我在应用程序上有一个模式,它将创建工作线程,以针对给定长度(每长度1个线程)执行可能的组合

你开始这个过程,然后它将以长度1、2、3、4、5、6、7、8开始,依此类推。 当长度较低的线程完成时,它会将可疑密码长度增加1,并生成一个新线程。 限制因素是ProcessorCount-1(为了避免线程锁定或GUI线程冻结:通常发现系统在有空闲内核的情况下更稳定)

因此,在4核系统上,您将处理密码长度1-3,当完成1,2和3时,它将继续移动到4,5,6,依此类推。 长度1-5几乎可以瞬间完成。 3-4秒内完成6-7次。 长度8可能需要30-45秒。 (这些时间取决于是否为数字/字母数字等) 更多可能的字符会增加我们需要检查的键空间

好的,这就是多线程的一种方法。 但是我想介绍的另一种方法有点复杂。 它涉及使用多个线程来使用固定长度密码的完整密钥空间。 我们知道它有8位数长,所以使用我们所有的线程更快地通过8位数的密码键空间

我不知道如何进行

例如: 假设我们的密码是100(1000个组合?) 我们的处理器上有8个内核 如果我们使用my-1方法,那么这就是7个潜在线程。 每个线程大约需要143个组合进行测试。 我只是想知道如何有效地计算每个线程的起始位置

例如:

线程1将以000开始,以142结束 线程2以143开头,以285结尾,以此类推

对于数字来说,这听起来很容易,但是当您使用一组可能的字符时—“abcdefghijklmnopqrstuvxyz1234567890”
如何计算起点和终点? 该字符串中有36个可能的字符。 3个字母的密码是否为36 x 36 x 36=46656个字符组合

好的,如果我有7个线程处理6666个组合。 如何将这些起始和结束位置转换为比较字符串

我想我的主要问题是: 如何将组合索引转换为由可用字符构造的字符串

例如:

  • 1可能是“a”
  • 2将是“b”
  • 37可能是“ab”等

    • 不会建议您这样做,但如果您想这样做,请像这样考虑

      你在角色1上有36种可能性,角色2上有36种可能性。同样的事情也适用于角色3。
      所以
      以第一个角色的可能性为例,通过6(线程)(7将是混乱的)
      为每个线程提供6个
      这是字符1的6种不同可能性,具有36X36种可能性

      这意味着线程1执行所有以a、b、c、d、e和f开头的操作
      线程2将执行g、h、i、j、k和l

      所以,

      不要让每一个线程搜索第1或第n个搜索空间,而是把它切成“逻辑”部分(即对你来说是有意义的)。这意味着您将创建比内核更多的作业,并且您的每个线程可以在完成前一个作业后拾取其中一个作业

      例如,对于数字8位密码,您可以创建任务0到9,其中任务n是“搜索所有以数字n开头的8位密码”。对于字母数字密码,您可以创建36个任务:“搜索以“a”开头的所有密码,“…以“b”开头,“,”以“0”开头

      将所有任务扔到池中,启动任意多个线程,并从池中为它们分配一个任务。任务完成后,让线程从池中取出一个新任务,直到任务用尽

      您可以使用a来实现这一点,但坦率地说,我只是自己创建了一个简单的机制,其中工作池是一个
      列表
      ,您可以使用一个简单的
      锁定
      机制在上一个操作完成后将任务从列表中删除


      编辑:快速创建一个示例。它看起来有很多代码,但相当简单。没有真正的测试,但应该给你一个线索,我的意思

      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);
          }
      }
      
      private List jobs=new List();
      私有对象jobsLock=新对象();
      //这是CPU密集型函数,用于检查密码的实际工作
      私有无效测试密码(整数长度){
      
      对于(int i=0;i<(1)您读过吗?如果可能是“a”,并且暴力计算需要3个字符长的密码,则需要“”(一个空白)也要在可能的字符列表中,否则它将永远无法到达。它将以“aaa”开头。另一个问题是,如果您确实将其添加到列表中,那么可能的密码可能是“a”和“a”,因此您需要考虑这一点。是的,可能的带有n个符号的k字母单词的数量是n^k。例如,有10个十进制数字数字和可能的3位数字的数量是…10^3。即使在你获得10个字符的密码之前,你的暴力方法也需要一段时间。36^7是780亿,并且会发生变化。至于如何将索引转换为字符串,这很简单。进行基数转换。也就是说,以36为基数输出你的数字。算法与转换没有区别任何其他基地都可以。