哪个更快 - 暴力破解或使用包含所有可能排列的字典攻击?

信息安全 密码 蛮力 密码破解 字典
2021-08-28 08:59:10

假设一个 6 字符的密码使用 mixalphanumeric 字符集,给每个字符一个 62 个字符集,给整个密码一个62^6 = 466 亿的键空间(如果我的计算是正确的)......

暴力破解密码,或者在字典中生成整个键空间并在字典攻击中使用该字典会更快吗?

这两种方法是否被认为是等效的,还是在性能上有差异?后者经常做吗?如果不是,为什么不,如果是,为什么不更常见?

请注意,提到的示例就是这样,我要问的问题是关于这两种方法的性能问题,而与特定密码的密钥空间和实际花费的时间无关。

3个回答

没有区别......直到你进入实现。

高效的破解平台(如 hashcat 和 John the Ripper)直接在 GPU/CPU 上执行暴力破解,使用优化使它们比从外部字典输入破解过程中的等效候选密码要快得多。

真正的暴力破解和相关攻击(如基于掩码和基于规则的攻击)应该总是比纯字典攻击更快。

更新:我的回答适用于快速哈希。帕斯卡的回答是正确的,如果哈希足够慢,那将是相同的。

任何有意义的答案都必须考虑一些细节,例如使用哪个哈希函数来保护密码。

如果您创建了一个包含所有可能密码组合的字典,以“111111”开头并以“zzzzzz”结尾(假设只有大写字母、小写字母和数字),并且您没有按密码可能性对该字典进行排序,而是保留了它按字典顺序,问题会变成哪个更快 - 将这些字典字符串输入您的密码猜测器或让密码猜测器即时创建组合。

要回答这个问题,我们必须知道我们将字典存储在哪里,它足够大,我们可能无法将其完全放入内存,因此我们需要将其存储在硬盘上。

同样重要的是要知道硬盘驱动器(无论如何都是磁性旋转磁盘变体)的访问时间在毫秒范围内。RAM 的速度要快几个数量级,但与 L1 缓存相比仍然很慢,后者又比 CPU 中的直接寄存器访问慢得多。不幸的是,通用 CPU 寄存器总共只能存储 128 个字节,而 L1 缓存总共只能存储几个 kb。

再次假设您正在使用一台留有 8 GB 内存供您使用的计算机,您可以同时在 RAM 中保留大约 10 亿个字典条目。这大约是整个密钥空间的 2%。

如果您从硬盘驱动器加载字典,则总共需要加载 325 GB 的数据(每个可能 4 GB 的垃圾数据 - 在尝试其他 4 GB 的密码时,您总是会加载 4 GB 的密码)。即使使用 SSD,这也需要一段时间。

现在,如果您正在处理像 md4 这样的哈希函数,hashcat 很容易在您加载下一批之前耗尽您的候选密码,因为在现代 GPU 上它可以每秒测试数十亿个密码。实际上,您无法从硬盘快速加载候选密码。另一方面,如果您试图攻击使用 bcrypt 等哈希函数加密的密码,从硬盘加载候选密码甚至不会减少成功攻击密码所需的时间,因为即使是现代 GPU 也无法bcrypt 的速度足以在下一个 5 亿个候选者从硬盘加载之前耗尽 5 亿个候选者。

让我们看看动态创建密码,而不是将它们大量加载到 RAM 中,是否会更快:

CPU 有一些有趣的特性。例如,他们使用指令预取、分支预测和试探性执行来在实际知道是否应该执行代码之前执行代码。与 CPU 缓存一起,这意味着如果您运行一个非常小的、紧凑的代码,例如枚举给定位长度的所有可能组合的代码,它基本上可以完全在 CPU 中运行,永远不会接触(慢)RAM . 小密码(6-8 字节)很容易放入单个 CPU 寄存器中,16 字节密码仍然适合两个寄存器。从最后一个密码生成下一个候选密码的代码就像使用“add”指令一样简单,这是最快的 CPU 指令之一。所以我'

但同样,CPU(或 GPU)计算实际 bcrypt 哈希以与哈希密码进行比较所需的时间将使生成候选密码所需的时间相形见绌。

因此,密码生成方法对于受到良好保护的密码来说并不那么重要。仅在处理弱或非常快的哈希函数(例如 md4、md5、sha1 等)时才重要。

结论

如果您假设每个密码的可能性相同,那么动态生成所有密码(暴力破解)更有意义,因为您不需要在硬盘驱动器上保留大量字典。您可以在运行中更快地创建它们。这就是为什么没有人在他们的硬盘驱动器上保留未分类的密码字典以进行愚蠢的暴力破解。

另一方面,如果您承认某些密码(认为“123456”和“密码”比其他密码更相似(认为“1qHGmR”),那么创建这些密码的字典并将该字典加载到 RAM 中,并且可能使用一些从基本字典条目“sarah”创建衍生词(例如“sarah1997”和“sarah1998”)的规则是可行的方法,因为它几乎总是会快得多。

也就是说,如果您实际上是在处理 6 个字母的密码和一个弱哈希函数,那么这两种方式都没有多大关系,因为 hashcat 和同胞可以在几分钟、几小时或几天内通过蛮力耗尽 6 个字符的密钥空间,取决于使用的散列函数和可用 GPU 装备的能力。

从实现的角度来看,可以肯定地说,拥有一种知道它正在执行蛮力的算法会更快,而不是一个一个地通过查找表,这会固有地为每次尝试增加查找开销,而这不会存在于前者。

例如,您的算法将更快地在代码中使用嵌套循环进行暴力破解,而不是每次尝试都需要一个额外的查找步骤(磁盘读取或内存读取)。