在所有这些答案中,我正在考虑从被盗散列中恢复密码(或等效密码)的问题,该散列存储在攻击者可以获得读取访问权限的服务器中。
NTLM 散列很弱,但没有旧的 LM 散列那么弱。
旧的 LM 哈希包括几个资本弱点:
- 不区分大小写。
- 限制为 14 个字符。
- 将密码分成两个 7 个字符的部分,分别进行哈希处理。
最后一个弱点允许非常有效的破解(无论选择密码时是否小心);有关详细信息,请参阅此答案。
较旧的 NTLM 只是通过密码计算的MD4 。这一次,密码区分大小写,并且可能很长。关于真正的最大密码长度存在一些争议,显然可以达到 127 个字符左右。由于 MD4 是通过密码的 UTF-16 编码计算的,理论上可以使用整个Unicode范围,但是由于用户需要定期输入密码(并且没有视觉反馈),因此使用超出可打印 ASCII 集的字符正在寻找麻烦。
NTLM 散列的弱点在于它是无盐的,而且 MD4速度很快(MD4 也以多种方式被密码破解,但不是用于密码散列的原始原像抗性;为此,MD4 与以往一样强大曾是)。MD4 实际上比 MD5 快。最近的 GPU每秒将计算数十亿个 MD4 实例。这使得攻击者可以轻松探索大量潜在密码(即所谓的字典攻击)。唯一的防御措施是从更广泛的集合中选择您的密码。
让我们对其进行一些数学运算:由于 NTLM 是无盐的,因此一组专门的攻击者可能会发现构建一个大彩虹表是值得的。有各种可能的优化,但通常情况下,事情会是这样的:
- 有一个安全参数,称为t;这是彩虹表中链条的平均长度。
- 如果表所涵盖的密码集大小为N,则存储需求约为10*N/t字节(每个排序链端 10 字节是合理的估计)。
- 构建表需要大约1.7*N次散列函数调用的成本。
- 用表攻击一个密码需要计算大约t 2倍的散列函数,并在表中进行t次查找。
如果将表拆分为一百多个机械硬盘,则每秒可以进行大约 10000 次查找。如果攻击者真的有动机,他可能希望每个密码花费一小时左右,这意味着查找的最大t为 3600000(假设为 2 22);相应的 CPU 成本下降到每秒大约 2 32 个哈希,这对于最近的几个 GPU 是可行的。100 个磁盘允许 300 TB 存储(我说的是 3 TB 磁盘,现在是现成的),这使可能的N达到大约 2 67。这是相当大的,但在技术上是可行的。我们的攻击者组可以购买一百个 GPU(以及一个大 空调机组)并在几个月内完成计算该表。
因此,为了打败我们有动机的对手,我们需要从大于N的集合中随机选择密码。如果我们的可能密码集合的大小超过 2 77,并且我们的密码是在该集合中随机且均匀地选择的(即密码熵为 77 位或更多),那么攻击者只有 1/1000 的机会破解给定密码他的桌子。这应该足以劝阻他。
我们如何获得 77 位熵?如果我们将自己限制为字母(大写和小写)和数字,以便可以在任意键盘上输入密码,那么每个字符的熵可以少于 6 位。因此,13 个字符就足够了。是不是膨胀了?只有13个!无需使用大量密码。但请注意小字体:那是13 个完全随机的字母或数字。毫无疑问,让人类选择这些字符,甚至生成十几个 13 个字符的密码并让他选择他最喜欢的一个。您拿起生成器,生成一个密码,然后学习它。脑力劳动是使用像 NTLM 这样的无盐快速密码散列机制的代价。
(当然,上面描述的攻击者组是现实的。您可能希望稍微增加复杂性,以便您的密码对于明天的攻击者来说也将是强大的;所以将其设置为 14 或 15 个字符更安全。)