答案是没有那么简单。在说复杂是好是坏之前,了解攻击密码的所有方法很重要,因为不同的要求旨在阻止不同类型的攻击。
正如您所指出的,给定来自同一字符集的两个同样长的密码,密码复杂性要求确实会减少整体搜索空间。例如,给定一个必须包含一个字母的 1 个字符的 ASCII 密码与一个可能是任何字符的 1 个字符的 ASCII 密码,更容易猜出第一个密码。
但密码字符要求不应用于排除长度。考虑以下密码要求集的最小强度:
- 8 个可打印的 ASCII 字符 = 大约 100^8 = 10^16 个可能的值
- 16 个可打印的 ASCII 数字 = 10^16 个可能的值
- 9 个可打印的 ASCII 字符,至少有 1 个数字、1 个字母(任何大小写)和 1 个符号 = ((10 个数字) (52 个字母) (30 个符号)*100^6) = 10^16
[注意:我知道 100 不是真正的数字,它只是让数学更容易]
所以我们看到三种不同的密码要求在蛮力要求方面同样强大。但是我们还没有对字典攻击做任何事情。在字典攻击中,我们只需测试一个众所周知的单词列表,看看其中是否有密码。让它们中的任何一个更长,你就让它比其他的更强大。
密码要求 1 对防止字典攻击没有任何作用,而 3 几乎没有作用。您可以使用字典中极有可能出现的“预防”一词。您可以查看已在 Internet 上泄露的真实密码列表(或创建您自己的流行服务并收集密码)并发现流行密码以优化您的攻击以获得最可能的值(例如,如果纽约的每个人都选择了“Yankee1!”,那么你的攻击将从尝试“Yankee1!”的变体开始)。
所以接下来自然要做的事情是防止密码是字典单词。这减少了有效密码的数量,但它也消除了攻击者可用的优化。使密码稍长一点,您可以保持无字典单词密码的强度或强度相同。
但这对 leet speak 密码没有任何作用。您不会在字典中找到 P4$$w0rd,但它是蛮力工具测试的一个非常标准的变体。提取字典中的每个单词,通过 leet speek、前置、后置运行它,并在每个位置插入一个或两个其他字符。
然后可以引入密码复杂性要求来限制这些类型的攻击 - 多个符号、多个数字和(再次)更长的密码。需要密码管理工具来跟踪的东西。蛮力很难(因为它越来越长)并且很难优化,因为它不在字典中,也不像字典中的任何东西)。
但是,当您破解特定密码并且用户更改为新密码时会发生什么?用户经常尝试做简单的事情,并选择一个容易记住的密码 - 一个与以前非常相似的密码。P4$$w0rd1 变为 P4$$w0rd2。但是攻击者只需将 P4$$w0rd1 添加到他的字典中,他就会自动测试 P4$$w0rd2。因此,通常不允许重复使用密码。
但问题的核心是,“它是否适合组织的需求?” 考虑到我们甚至还没有开始讨论的所有其他补偿控制,您需要一个足够强大的密码以确保它的安全性(例如,它已更改或帐户被禁用)。如果暴力破解速度很慢,或者你只有很少的机会,那么较弱的密码是可以的(例如,IronKey 允许 17 次尝试并且需要物理访问,所以 10^16 的密码已经足够强大了)。