C#Bruteforce-多线程处理固定长度密码
我一直在研究一种算法来进行暴力强迫。与其说是恶意使用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”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核系统上,您将处理
如何计算起点和终点? 该字符串中有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为基数输出你的数字。算法与转换没有区别任何其他基地都可以。