delphij's Chaos

选择chaos这个词是因为~~实在很难找到一个更合适的词来形容这儿了……

22 Dec 2011

密码阴谋论

大家都喜欢阴谋论,所以今天说个关于密码的。话说,假如你拿到了一个大网站的密码数据库,然后恰好这个数据库里面的密码又都是明文,但这个数据有点旧了,怎么样才能立即得到其中的活跃用户的密码呢?

假设你可以控制若干家网络公司所使用的网络基础设施,例如事先装了一些监控非法活动的防火墙的话,方法就很简单了:公布这个数据库,或者公布至少其中的一部分,然后做简单的监听就可以了。这个过程不但可以知道他们的新密码是什么,而且可以知道旧密码是否是对的,还可以知道他们的安全习惯如何,要知道,假如没有这个事件,绝大多数人可能正靠着他们的简单密码睡大觉。

当然,攻击者显然还会注意到,这些网站,以及很多其他网站,多数还都没有对用户做最起码的保护,即使用 https 来保护登录过程。

一个显然的预防措施是,每个网站都用不同的、随机生成的密码。最差情况下,丢失一个明文密码的代价仅限于那个网站。

把密码记在心里是预防密码表被盗走的最好途径。但是记不住怎么办呢?最近几年的研究表明,把这些密码记到纸上是一个还凑合的折衷方案。把密码(显然,不包括与之对应的网站和用户名)抄写在一张作弊条上,放在钱包里;另外留一张放在家里。这种方法要好过密码管理器,原因是很多人并不知道自己被种了木马,而密码管理器可以在受害者毫不知情的情况下把密码表如数交给攻击者,而钱包丢了这种事情通常的人很快都会注意到并及时采取措施。

作为互联网产品的产品经理还应该考虑什么呢?以下是我想到的几个可以考虑的方面,仅作抛砖引玉:

第一个,也是非常非常重要的,就是凡是跟用户隐私有关的东西都做最大限度的防护。例如,用户的个人信息只应保存在特定的一组服务器上,用户的密码应该使用带salt的hash存放而无论如何不存明文或加密的明文数据,以及凡是需要显示用户隐私信息,例如用户的真实姓名、地址或者好友关系等等的时候,以及要求用户提交隐私信息的地方都采用 https,注意需要 https 保护的不仅是处理提交的服务器,也同时包括提交表单、图片、CSS以及全部相关脚本所在的全部服务器。

第二个,是尽可能避免让用户经常进行登录操作。例如,在用户登录时产生两个信任状,其中一个过期时间非常长(假如用户客户端是安全的,这个过期时间可以是一个月甚至一年),而另一个过期时间则较短(几分钟到十几分钟)。使用前一个来向用户展示那些不太涉及隐私的内容(例如查看公开的活动列表、推荐的产品目录、检查是否有新消息以及消息的数量等),而后一个则用来展示需要涉及隐私或确认的内容(例如查看消息列表、处理好友关系、确认订单等)。因为用户每次输入密码都可能是一次安全风险,而且过多要求输入密码会令用户反感。另外,采用统一的集中认证机制,如 OpenID 等,也是值得提倡的方法。

第三个,是对可疑活动的监视和对用户的提醒。针对北美市场的互联网产品,可以设计在用户使用不同的 IP 登录时进行提醒;针对中国市场的互联网产品,可以在用户采用不同的桌面系统登录时进行提醒。

第四个,是不要只用密码来做验证,例如,可以集成 Google Authenticator 或类似的东西。

最后,也是老生常谈的问题,是对登录的速率限制。同一个客户端或同一个用户名在一段时间内做身份验证的速率必须做限制和锁定操作。这个做法的主要目的是防止密码穷举,而对于没有异常行为的客户端或用户要求输入验证码是十分反人类的行为,应尽量避免。