Skip to main content
  1. Posts/

粉碎字典:设计方便记忆的安全口令

·

就算无法逃避社工,也要设法减少损失。

最近又心血来潮把所有重要账号的密码改了,在这个过程中产生了很多想法,记录一下。

常识 #

我们知道,尽管扫码登录、手机验证码登录已经十分普及,传统的账号 + 密码依然是主流的登陆方式。为了避免和密码学术语混淆,这里说的 “密码” 实际上指的是“口令”。如今应该不会再有人用类似 123456 这样的口令了,然而在渗透过程中,我发现许多用户、乃至许多系统的口令依然只是做到了比 123456 强一些而已。因此,关于口令的设置,首先需要明确一些常识。

攻击 #

站在攻击者角度,如果他想要窃取你的口令,一般会如何下手呢?最常见的方法不外乎暴力破解和字典攻击两种。

暴力破解 #

如果攻击者已经知道你的口令是 6 位纯数字,那么他的思路就非常简单:从 000000 到 999999 逐一尝试直到成功为止;如果是 6 个字母组成的单词,那就枚举每一位上的 26(52)种可能性。只要时间够长,这种方法总能成功,然而问题在于当口令的长度和字符集增长时,暴力破解所需要的时间代价也飞速增长,使得这种方法在大部分场景下没有什么实用价值。为了缩小枚举的空间,攻击者常常选择另一种手段类似的方法:字典攻击。

字典攻击 #

假设你的口令是上面说的 6 个字母组成的单词,攻击者可以靠查字典来大大缩小需要枚举的范围————毕竟,许多 6 字母组合并不能构成单词。当然,这么说是一种简化的情况。实际场景下的字典攻击,是攻击者先准备一本 “口令字典”,然后只枚举在这本字典上出现过的那些口令。问题在于攻击者如何制定这本字典来提升成功率的。

这里就利用了人们为了方便记忆,总是使用与个人信息相关的口令这一现象。个人信息泄露在这个时代已经是家常便饭,因此通过一些信息收集手段,从某一个人的一个虚拟账号查到其真实身份及个人信息并非难事。这种手段被称为社会工程学,而被攻击者的口令很有可能就在由此定制出来的字典中。

防御 #

那么作为防御者,我们需要考虑的也就是如何抵抗这两种攻击。抵抗暴力破解非常容易:

  • 口令尽可能包含大写字母、小写字母、特殊符号、数字中的至少 3 种
  • 口令长度不能太短,一般至少需要在 8 位以上

我们不妨称满足这两个条件的口令为爆破安全的

然而字典攻击就没那么容易防了,因为安全是方便的敌人:与个人信息相关的口令容易记住,却也容易被字典攻击破解;与个人信息无关的、毫无规律的复杂口令很难被字典攻击破解,但却很难记。这一矛盾在撞库攻击下更为突出。

撞库攻击,即攻击者获取到某人在某一网站上的口令(明文)后,用同样的口令尝试登录同一人在其它网站上的账号的攻击手段。

这种攻击的存在提醒我们:

  • 对于不同的网站账号应设置不同的口令,且每个口令都需要是爆破安全的

满足这样的安全性要求,可能会使一个人的口令非常难以记忆和管理。因此,许多人开始选择使用口令管理工具来存储和自动填充那些设置得十分复杂的口令。这是一种不错的办法,然而由于对一些口令管理工具安全性的担忧、以及在多个平台上装同一款软件的抵触,我依然倾向于依赖自己小小的灰色细胞。下面要介绍的,就是如何设计一套既便于记忆、又足够安全的口令方案。

需求 #

在开始之前,先来看一下我们设计方案的需求:

  • 对于任意两个不同的网站,方案产生的两个口令相同的概率是可忽略的
  • 对于任意一个特定的网站,在没有纸笔、计算器等任何辅助工具的情况下,可以在较短时间内(例:10 秒内)得到完整的口令
  • 所有产生的口令都是爆破安全的

实际上对于 “可忽略”、“较短时间” 都可以进行数学定义,这里就不赘述了。

方案设计 #

以生于 1975 年 6 月 2 日的张三为例,我们如何为他设计一套口令方案呢?

不可变部分 #

从最简单易记的名字 + 生日方式(也是很多人在用的方式)开始,我们首先获得了基础口令:

ZS19750602

这样的口令显然太弱了。我们可以对其应用适当的变换,例如用 k=6 的凯撒移位:

`Y7?=;6<68

具体应用哪种变换,取决于张三的脑洞、以及什么样的变换方式对张三来说比较容易计算。比如,他同样可以用一种规律比较杂的变换得到:

52I6_\2O905

这里涉及到将字符垂直翻转、以及一些形状相近字符的互换等操作。这次生成的字符串和原字符串长度也不相同。

总之,通过将容易记忆的(与个人信息相关的)字符串进行一种容易计算的变换,我们可以轻松生成口令的不可变部分

可变部分 #

而可变部分取决于该口令所属的具体网站。以 QQ 为例,我们可以用类似 qq / icq / imqq 等作为网站的特征。随后对网站特征进行变换,例如 qq 可以变换为 9g / 11371 / 1wwa 等(分别用了形似字替换、ASCII、键盘等规律进行变换)。这里需要注意的是对于同样的字符 q 应该变换出不同的结果,并且这里的变换方式不应与不可变部分的变换方式相同。

这样,通过提取网站特征并进行另一种容易计算的变换,我们得到了口令的可变部分

那么张三最终的 QQ 口令就可以是:1wwa52I6_\2O905。当然还可以加一些连接符,如 1wwa&52I6_\2O905

由于在上述步骤中,采用的变换、网站特征、原字符串都需要选取容易记忆的,我们可以确保该口令方案也是容易记忆的。问题是,这样的方案足够安全吗?

安全性分析 #

从密码学角度,这样的方案是不安全的,因为其核心就是 * Security through Obsecurity*,这是违反 Kerckhoff 准则的。而且,这样的方案缺乏随机性,不可能是安全的。然而随机性恰恰是记忆的最大敌人,这使得我们不能在方案中引入随机性。

不过对于个人使用而言,可以认为该方案足够安全。在分析方案安全性之前,我们不妨先讨论一些安全的定义。

定义 #

为了定义一种口令方案 “有多安全”,我们可以站在攻击者的角度:攻击者为了获取口令所需要付出的代价越大,那么可以说这种口令方案越安全。不妨称攻击者为 A,被攻击者为 B,下面就给出一些攻击者具备不同能力时的场景:

  • 弱社工攻击:A 只能获取到关于 B 的一些基本社工信息,如姓名、生日、证件号码等,尝试获取 B 在随机某一网站上的口令
  • 强社工攻击:A 有能力获取到任何与 B 有关的社工信息的每一个细节(A 比任何一个熟悉 B 的人更熟悉 B),尝试获取 B 在随机某一网站上的口令
  • 已知口令攻击:上述基础上,A 有能力获取 B 在随机某一网站上的口令,尝试获取 B 在指定网站上的口令
  • 选择口令攻击:上述基础上,A 有能力获取 B 在指定网站上的口令,尝试获取 B 新注册的网站上使用的口令

讨论 #

可以看到,攻击者的能力是递增的。由于经过变换,口令看起来与社工信息无关,这足以保证口令不会出现在攻击者构造的字典中,使得强社工攻击难以成功;对于已知口令攻击和选择口令攻击,攻击者需要对获得的口令进行分析,以掌握口令方案中采用的两种变换、网站特征、原字符串————后两者不难猜解,而安全性的核心,即采用的两种变换如果选取得当,在已知口令攻击下是极难猜解的。这是因为已知口令情景下攻击者还需要区分可变和不可变的部分。

而对于选择口令攻击,攻击者可以很容易得到不可变的部分,那么最后的挑战就仅仅在于猜解两种变换。此时两种变换的设计就极大程度决定了方案的安全性。由于更安全几乎总是意味着更难以记忆,这里的设计可以根据个人需要来调整。如果使用类似凯撒移位这种变换,想要抵抗选择口令攻击是比较勉强的。

不过话说回来,选择口令攻击确实是极端的情景————因为此时攻击者必须要掌握你所有网站上的口令才行。现实中的撞库攻击一般更接近已知口令攻击,而我们的方案可以很好地抵御这类攻击情景。

总结 #

我们可以这样设计既容易记忆、又能抵抗常规情景下字典攻击的口令方案:变换 1(网站特征) || [连接符] || 变换 2(可能与个人信息相关的字符串);这种方案本质上是一种将 可能与个人信息相关的字符串 这类弱口令与 网站特征 关联从而生成动态强口令的方案。