一条密码走天下 - 1pass4all简介

Hui Zheng Feb 26, 2012 project 1pass4all  project  JavaScript  software  bookmarklet  password  security 

一条密码走天下

在这个互联网时代,网络账户大都是以用户名与密码组合的形式来鉴别的。由于 用户名一般是公开的,密码安全就显得至关重要了。设计一个好密码绝非易事,既要 足够强壮又要易记难猜。强密码的一个典型特征是熵(entropy)值高,通俗地说是 随机性强、规律性弱。那些用有规律或广为人知的数字序列或字串组成的密码固然不满足此条件, 一个长度不够、字符取值范围不广的密码在暴力破解面前同样弱不禁风。此外,有些密码 看似强壮,但如果与用户的个人信息紧密相联,也容易被知情人猜出或缩小检测范围。 事实上,绝大多数用户的密码要么不够强壮、要么容易猜测、要么(也是更多的)兼而有之。 去年底爆出的“密码门”事件再次佐证了这一点。 其实情有可原,强壮而难猜的密码通常也难记。有些用户挖空心思地想出强密码,为不增加 设计负担和记忆负担,往往又忍不住在多处网站重复使用,就此埋下安全隐患: 一旦由于某种原因(如此次“密码门事件”)密码被暴露,将殃及多个账户。故而 对密码的另一要求是,不同账户的密码应尽可能不相同、甚至不相关。只不过这样一来,密码 维护的难度更是倍增。正因如此,一些密码管理软件应需而生,它们的核心思想基本上都 很相似, 即以加密的形式为用户保存所有的账户和密码信息,用户仅需记住一条密码 (以下称为“主密码”),便可随时查询内藏的密码库。

本人使用密码管理工具颇有时日,包括KeePass1PasswordLastPass, 始终觉得它们各有缺憾。KeePass在功能和界面上不如1Password,但后者价格不菲,且主要 在Mac平台(后虽支持Windows,但界面上远逊,且不支持Linux)。LastPass相比前二者的 优势是支持云同步,但将密码库置于远程服务器也非全无顾虑,比如TechCrunch曾刊载 过LastPass被破解的传闻。另外,虽然这些管理器都能帮用户生成 随机密码,但既难记又难敲。您可能会问:为什么要记呢,这不正是它们的意义所在吗? 话虽如此,然而不可否认,每登陆账户都要额外启动一个程序委实不便。不错,用户可以选择 让浏览器记住密码,或者利用这些管理器在浏览器上的插件来自动填写,但这种便利是以 安全为代价的。我以前的做法是,自定义一些隐秘的变量,然后通过某些规则或函数 进行变换而产生密码。作为一个程序员,我甚至写了一些脚本让此过程自动化。可惜该法 有个弊端:一旦离开自己的电脑,便可能因缺乏脚本或脚本运行环境而失效。 某日细思此事,想到JavaScript当是比一般的脚本更佳的选择,盖因凡有电脑处便有浏览器, 凡有浏览器处便能运行JavaScript。只要把JavaScript代码上传到某个网络空间,即可 予取予求。由于运行的过程与结果既不会在网络中传输,也不会在本地保存,有效保障了 密码的安全性。于是,很自然地开始把焦点集中在 小书签(bookmarklet)(或译为“书签工具”)上。所谓小书签, 无非是放在浏览器上的一种书签或网页上的一个超链接,与普通书签或超链接不同的是, 其网址(URL)不是某个网页地址,而是一段JavaScript代码。一旦被点击, 不会如普通书签那样进入到新网页,而会在当前网页中执行其内含的JavaScript程序。 此法方便、易安装、跨浏览器、且无干扰(unobtrusive) (注:不少人译为“无侵入”,但对应后者更贴切的英文当是unintrusive或non-intrusive)。

为避免重复劳动(即所谓的“重新发明轮子”),先在网上查寻是否已有现成产品可用, 结果发现SuperGenPass较好地满足了自己的要求。简单地说,SuperGenPass能将 一个主密码按不同的网站域名转换成不同的密码。不出意料,它采用的是MD5 算法。此算法可迅速将主密码与网络域名的组合单向(one-way)映射(计算机术语 是哈希(hash))为一个对输入敏感的、近似随机的字串。“单向”意味着 从输出难以反推输入,从而一条密码泄露不致暴露主密码;“敏感”意味着差异微小的输入 会导致差异极大的输出,从而一条密码泄露不会对其他密码造成危险;“近似随机”则意味 着输出字串可视为强密码。主意是不错,但于我并不新鲜。何况已知有人用SHA-1 开发了密码生成器,年前还见有国人用 MD5实现了类似功能。 SuperGenPass真正令我心动的地方是,它能就地生成密码——在用户于密码项中填入 主密码后,点击小标签便能用新产生的密码直接替换主密码。相比之下,原先在命令行中 运行脚本再将结果拷贝或重敲一遍的做法,既不安全也不方便。

事情变得简单多了。有了密码小标签,只需牢记一条密钥在心,便能自信地在不同的 网站以不同的强密码登陆,哪怕与这些密码素不谋面。不过传统的密码管理器 仍有用武之地。比如可以记录主密码的提示,以防万一哪天“临时性”失忆;可以 在可信赖的电脑上为非关键性的账户提供自动填单的功能;可以保存其他类型的 敏感信息或文件,等等。

在准备采用SuperGenPass之前,对其功能和源代码进行了一番考察,很遗憾地发现有些 缺陷令人难以释怀。首先,MD5在理论上不够安全。作为一个文件校验器 问题还不大,作为密码生成器则有些勉为其难了。更糟的是,SuperGenPass默认的 密码盐(salt)为空,且除非修改源代码便无法定制。这使其极易受到 字典攻击。另一问题是,SuperGenPass基于Base64, 这意味着生成的密码主要有字母与数字组成(此外还有+/),许多如?!$ 等特殊字符均被排除在外。这便是此前所说字符取值狭窄的问题。以一个8位密码为例, 64种字符的组合数不到94种字符(可打印字符共94个)的组合数的20分之一,相差一个数量级。 若是12位密码,比率更是低于百分之一,整整相差两个数量级。再者,SuperGenPass完全 不考虑用户名也是一大不足。本人在一些网站(如gmail、dropbox)上有多个账户,非常不 希望它们共享密码。诚然,给主密码加上用户名前缀或后缀便能衍生出不同实际密码。但 从名义上看,单个主密码的说法便已然不实;从理论上看,将密钥与数据简单地用字符串 拼接的做法不如HMAC算法更可靠。此外,在变更密码页中,SuperGenPass似乎 有点问题。不知为何,有时它自动将旧密码、新密码和确认新密码三项均作变换,有时却 只改变其中的一个或两个。权衡再三,最终决定自己从头开发一个密码小书签,这便是 1pass4all (意即one pass for all,一码永逸) 的由来。

1pass4all希望在SuperGenPass之上有如下改进:

和SuperGenPass一样,1pass4all也提供了移动版。有时用户不能或不想安装小书签,比如 在手机上、在他人电脑上、或在可能会盗取主密码的非信任网站上。另外,要想在非浏览器 应用上使用1pass4all,目前也非移动版不可。

对高级用户(尤其是程序员),则推荐使用自制(DIY)版,不仅可更随意地定制参数、 设置JavaScript代码的网址、改变界面的风格(以弥补原有界面的简陋),必要时更可修改算法。

若此文引发了您的些许兴趣,不妨到安装页面 一试。更多说明请参见README文件。如有任何问题或建议,欢迎留言。 需要提醒的是,尽管1pass4all能极大地强化弱密码,但由于其算法是公开的,因此主密码 仍应足够强壮。如是,纵然“一条密码走天下”,亦可高枕无忧矣。

附:本文的英文版

参考文献

[1] SuperGenPass

[2] Wikipedia: bookmarklet

[3] Wikipedia: Unobtrusive JavaScript

[4] Wikipedia: MD5

[5] Wikipedia: Cryptographic_hash_function

[6] Wikipedia: Salt_(cryptography)

[7] Wikipedia: SHA-2

[8] Wikipedia: HMAC