密码是如何被破解的?

账户被攻破的方式很少像电影里演的那样。实际上,密码通过三种途径之一被获取。被破解:通过逐个尝试候选密码得出,通常针对从某个服务窃取的密码哈希数据库。被窃取:在假冒页面上被输入,或被恶意软件复制。或者被复用:攻击者从以前的泄露中拿到密码,到其他服务上尝试,指望主人在那里也用过它。这种区别很重要,因为每种途径要靠不同的手段应对。本文逐一介绍主要方法,并说明针对每一种什么有效。

数据泄露中的复用密码

每年都有服务遭到入侵,其用户数据库被出售或公开传播。攻击者从一次泄露中取出电子邮箱和密码的组合,自动拿到银行、邮箱服务商、网店和社交网络上尝试——这种攻击称为撞库(credential stuffing)。它完全不涉及猜测,而且奏效的原因很简单:人们会重复使用密码。如果到处都是同一个密码,即使是强密码在这里也帮不上忙。

有效对策:每个账户使用不同的密码,这样一个服务的泄露不会打开其他任何东西。

网络钓鱼

钓鱼页面是真实登录页面的副本,位于一个略有不同的地址上,人们通过电子邮件或口吻紧急的消息里的链接到达那里:账户被冻结、包裹、账单。您在那里输入的任何内容都会直接到达攻击者手中。密码的长度和随机性在这里毫无作用,因为是您自己输入的。

有效对策:通过自己的书签打开网站,而不是点链接。使用密码管理器:它只会在保存密码时的地址上提供填写,因此如果它没有提供已保存的密码,手动输入之前先检查地址。并开启双重认证,这样仅凭被盗的密码不足以登录。不过,一次性验证码也可能像密码一样被钓走。通行密钥和 FIDO2 安全密钥则不会以这种方式被钓走,因为它们只响应真实的网站——NIST 把这种区别称为抗钓鱼性。

恶意软件

被称为信息窃取程序(infostealer)的程序会复制浏览器中保存的密码以及会话 Cookie,并在运行后几秒钟内发送出去,而键盘记录器(keylogger)会记录输入的内容。被盗的会话 Cookie 可以让攻击者进入一个已经登录的账户,既不需要密码,也不需要第二因素。这类程序通常随盗版软件、虚假更新和电子邮件附件而来。

有效对策:只从官方来源安装软件,保持系统和浏览器更新,把意料之外的附件视为危险——但这些都不是保证。如果设备已被感染,请在另一台确认干净的设备上操作:更改密码,使用各服务的“退出所有会话”选项,并检查恢复邮箱、手机号码和双重认证设置是否仍属于您。在重新登录受感染的设备之前,先把它清理干净。

在登录表单上猜测

直接在网站上尝试密码很慢:设计良好的服务在几次错误尝试后会延迟、锁定或要求验证码。这让反复攻击单个账户效率低下,因此常见的做法恰恰相反:拿少数几个最常见的密码——123456、password、qwerty123——去尝试数百万个账户,这称为密码喷洒(password spraying)。定向猜测用个人信息以同样的方式进行:孩子和宠物的名字、生日、喜欢的球队,这些在社交媒体上都很容易找到。

有效对策:任何既不常见、也不是由您的个人信息构成的密码——参见如何创建强密码。

离线破解被盗的哈希

设计合格的服务不会以可读的形式存储密码。它存储的是哈希——单向函数的输出,无法据此反算出密码。这样的数据库泄露后,攻击者会测试可能的密码:在自己的硬件上计算候选密码的哈希并比对结果。没有登录表单拖慢他们,速度取决于服务选用的哈希函数及其设置。对于 MD5 这样快速而过时的函数,一张现代显卡每秒可以测试数百亿个候选。专为存储密码设计的函数——Argon2id,或旧系统中的 bcrypt——刻意放慢速度,把这一速率降低许多个数量级,这正是当前的建议点名推荐它们的原因。

字典攻击

候选密码并不是随机的。破解工具先从以往泄露中的真实密码列表以及单词和名字字典开始,再套用模仿人类习惯的规则:首字母大写、末尾加年份或感叹号、用相似的符号替换字母。像 Summer2024! 这样的密码看起来复杂,却是最先被尝试的候选之一。加盐(salting)——在计算哈希前给每个密码加上一个唯一的随机值——能阻止攻击者使用被称为彩虹表(rainbow table)的预计算表,也能防止一次性破解所有相同的密码,但它并不能让可预测的密码变得不那么可预测。

暴力破解

字典用完之后,剩下的就是尝试每一种组合,而对于随机生成的密码,决定结果的是长度。举个例子:假设使用快速哈希,密码的每个字符都从 94 个可打印 ASCII 字符(不含空格)中独立、等概率地选取。这样的 8 位密码约有 6 × 1015 个;以每秒一百亿次猜测计算,全部试完约需一周,平均在一半时间内就能找到正确的密码。对于 12 位,在同样的硬件上全部试完约需 1.5 百万年,而 16 位所需的时间已无法作任何有意义的比较。这就是支持长随机密码的全部理由:字典对它们几乎没有用处,在上述假设下,尝试所有组合也不现实。我们的强密码生成器在您的浏览器中生成这样的密码,并以比特显示每个密码的熵估计。

有效对策:一个足够长、不带任何人为规律的密码,在实践中也就是生成的密码。您无法控制服务如何存储您的密码,所以要做最坏的打算,选择即使用快速哈希函数存储也能抵御猜测的密码。

偷看与索要

最古老的方法不需要任何技术。密码被人从背后偷看到,从显示器上的便签上读到,或在视频通话共享屏幕时被看到;或者攻击者干脆冒充技术支持人员或同事直接索要——这就是所谓的社会工程。任何正规服务都不会通过电话、电子邮件或聊天向您索要密码。

有效对策:永远不要把密码说给或发给任何人,也不要把它放在别人能看到的地方。

总结

不同的攻击要靠不同的习惯应对,其中三个习惯能完成大部分工作:每个账户使用唯一的密码,由生成器生成而不是自己编,再加上双重认证——或者在服务支持时用通行密钥代替密码。它们并不能涵盖一切——例如被盗的会话——所以上文关于恶意软件的建议同样重要。更多文章收录在密码资料中。