前段时间,乌云曝光了网易邮箱存在的安全漏洞,尽管此事后来一波三折,网易一再否认,乌云也在漏洞页面上撤下了网易的名字,仅留下了「某邮箱」的字样,这其中的来来去去我们已经无从知晓细节,不过近来的确出现了非常多起以网易邮箱作为 iCloud 登录邮箱的用户,出现了 iPhone 被锁死的情况。

加之,前段时间曝出百度全系 Android 应用受 WormHole 漏洞影响,昨天 XcodeGhost 变种适应 iOS 9 卷土重来,晚间又有某知名社区遭攻击致帐号信息泄露……这些越来越多的隐私安全事件,让我们不得不对网络安全重视起来。

那么,密码作为一种最原始、最广泛使用的安全手段,到底应该如何设置?什么样的密码才是安全的?有没有什么好用的工具可以管理好自己的密码?甚至,如果我们能明白这些密码泄露事件的根源与原理,对我们加强安全意识会不会有额外的帮助?

在开始介绍具体的方法和措施前,我们希望先让您明白,密码到底是如何泄露的,正所谓知其然,也要知其所以然,密码安全不仅仅只是一些教条性的操作指南,更重要的是我们懂得在各个途径和过程中,如何保护好我们的密码。

密码到底是如何泄露的?

想要知道密码是如何泄露的,不妨先想一想,你的密码都在哪?概括地来说,它只会在三个地方:本地、传输过程中、远程数据库中

举个例子来说,如果你在浏览器中输入或保存了密码,这个密码在你点击登录前,只存在于你的本地,一旦你点击登录,浏览器就会将你的登录名和密码打包成为一个请求,发送给远程的服务器,这时候你的密码会经历一段非常短暂的旅程,最终到达远程服务器。如果你是第一次注册的话,你的密码还会以某种形式存储在对方的数据库中。

搞清楚了这个过程,我们来看一下各个环节里,都存在着哪些风险,会让你的密码泄露吧。

1. 本地泄露

1.1 恶意木马/恶意植入/键盘监听

电脑中病毒后,有些病毒只会在后台静悄悄地运行着,监控着你键盘上输入的每一个字符,然后偷偷发送给黑客。或者,前段时间的 XcodeGhost 事件,本质上也是应用程序中被植入了一段恶意代码,在后台偷偷地向远程服务器发送你的一些个人信息……

然而实际上,如果你能坚持使用可信任的设备,不安装未知来源的(盗版)软件,不对设备进行高危操作(如越狱、Root),感染恶意木马病毒的概率并不大。特别是在 iOS 系统上,得益于沙盒机制,每一个 App 的密码文件都单独加密保存,在不越狱的情况下,第三方是无法直接访问的。

建议:

  • 不在公共或有潜在安全风险的设备上进行密码操作;
  • 除非你非常有自信,否则请不越狱,不 Root;
  • 不安装未知来源的(盗版)软件。

1.2 伪造

伪造在 Android 平台上特别常见,也出现过由于 URL Scheme 的无验证机制,而出现的伪造情况。很好理解,如果你开发一款和支付宝长得一模一样的 App,或者抢先占用 alipay:// 这个协议的 URL Scheme,理论上你可以诱骗或劫持用户打开你的伪造支付宝来进行资金安全操作,试想如果你没有任何安全知识,仅仅看着界面一模一样的伪造支付宝,你又如何保证自己不被钓鱼呢?

建议: 从可信的源(如 App Store、Google Play)下载安装软件。

2. 传输过程泄露

2.1 明文传输

你有没有想过,当你在一个网页上点击登录时,到底发生了什么?大多数情况下,浏览器其实是向服务器发送一个 POST 请求,这个请求可能是长这个样子的:http://login.qq.com/id=10001&pw=immahuateng。发现了吗?你的登录名和密码是直接暴露在这个 URL 里面的。

尽管有些网站会对这个链接进行所谓的加密处理,但有些所谓的加密是不可靠的,例如仅仅只是把这些字符串转化为 Base64 码,或者用 Javascript 进行加密处理,或许对于小白来说已经完全看不懂了,但是对于真正的黑客来说,这些加密都是可逆的,很多情况下完全可以不费吹灰之力恢复密码的本来面貌。

如果是在一个不可靠的网络环境下,黑客完全可以使用 Wireshark 这样的工具拦截请求包,直接看到你的密码。

建议:不使用不可信的 WiFi 网络,特别是公共场合的陌生、免费 WiFi。

2.2 非加密传输

实际上,由于成本的考量,很多国内网站的登录页面使用的仍然是 Http 协议,而在国外诸如 Facebook、Twitter 这样的网站,早已经全站强制 Https 协议。只是多了一个 s,两者有什么不同呢?后者的传输过程是加密的,这样即使像前一种情况下有人拦截了你的数据请求包,他也无法获知传输的到底是什么内容。

当然,近两年随着国内网络安全环境的提升,越来越多的网站开始支持甚至全站使用 Https 协议,不过,像网易邮箱等网站,SSL 仍然作为可选项存在,虽然开启后对速度会有一定影响,但相比起开启后的安全性能提升,这点速度影响微乎其微。

对了,前段时间闹得沸沸扬扬的 OpenSSL 漏洞事件,实际上就是说这种加密传输的实现方法有一个漏洞,正所谓没有绝对的安全,对浏览器和网站证书也可以保持适当的关注。

建议:

  • 如果可能,使用 SSL 加密;
  • 保持浏览器在最新版本;
  • 检查网站证书是否可信(一般浏览器都会有提示)。

3. 服务器端泄露

就算你的本地计算机再安全,网络传输过程再可靠,然而一旦你使用的网络服务提供商不可靠,如果对方的数据库泄露(常称为拖库),那么你的密码安全一样岌岌可危。乍一看如果是对方的问题,好像自己也无能为力,不过一旦你了解到作为网络平台是如何存储用户密码的,那么还是能在密码设置方面为自己增加一些保障。

接下来的一些内容可能会有一些技术概念,不过我们为了方便大家的理解,尽可能地进行了简化处理,并加以例子说明。

3.1 明文泄露

什么是明文泄露呢?比如说你的密码是 123456,你所在的平台直接在它们的数据库里存下了你的密码 123456,是的,原封不动地存在数据库里。这意味着什么呢?对方的数据库一旦泄露,任何人,不需要借助任何技术手段,你的密码就直接展现在了他们面前。

听着好像很蠢,真的会有平台直接原封不动地把密码存下来吗?不要怀疑,想当年 2011 年轰动全网的 CSDN 泄露事件,作为一家技术网站,用户密码的保存就是用的原文。遇到这种事情,简直是叫天天不应,叫地地不灵。

建议:你选择不知道对方有多坑爹,直到……

3.2 可逆加密泄露

建议:如果说那些直接明文保存用户密码的公司很蠢,那么使用可逆加密的公司只是看起来不那么蠢而已。什么是可逆的加密呢?举一个很简单的例子,同样是保存用户的密码 123456,你可以设定一个规则,比如 1 对应 z,2 对应 y,3 对应 x,以此类推,那么最后存下来的密码就是 zyxwvu。发现了吗?可逆加密实际上是按照某个规则,加密后的密文与加密前的信息存在着一对一的关系。

由于可逆加密的这种可逆性,一旦数据库发生泄露,密码的暴露性实际上和明文差别不大,同样非常危险。

建议:对方可能以为自己不坑爹,实际也还是坑的……

3.3 不可逆加密泄露

相对于可逆加密,自然就有不可逆加密。你可能经常听说 MD5、SHA1、SHA256、SHA512、SHA-3 这些名字,实际上它们都是不可逆的哈希算法。

顾名思义,不可逆加密处理后,你无法通过加密后的密文直接反推出原密码,因为不存在一一对应的关系。这是如何实现的呢?比如说加密后的密文是 abcdefg,由于不对称性,生成这串密文的原密码可能是 123456,也可能是 woaisspai,它们经过哈希算法处理后的结果可能都是 abcdefg,这就保证了密文的不可逆性。

然而现实总是残酷的,即使是不可逆加密也并不是非常可靠。为什么这么说呢?由于任何人都可以模拟这些哈希算法,而现实生活中,又有许多用户的密码位数过短,或者设置的是同样的密码,这就会导致一个结果:即使经过加密后,很多数据库中存储的加密后的密文,由于它们对应的原密码是相同的,所以经过加密后生成的密文也是一样的。

甚至,黑客们专门制作了彩虹表。什么是彩虹表呢?就是预先模拟了一个数据库,这个数据库中穷尽了各种可能的密码组合,实际上就是一种暴力穷举的破解方法。黑客们可以将泄露的数据库中的加密值与预先准备好的彩虹表进行查找配对,一旦发现同样的密文,虽然不可逆加密的密文在理论上可能对应多个原始值,但由于有些密码的通用性,其反推的结果中,各个可能的原始值可能性却是不一样的。

而且这件事情并不难,举个例子来说,普通我们认为只要密码位数够长、组合够复杂、有大小写 + 数字 + 特殊符号总安全了吧?而事实情况是,一个由大小写字母 + 数字 + 部分特殊符号预先设立的彩虹表,穷举所有 14 位及以下的密码可能加密值时,整个彩虹表的大小也不过才 64GB,在当今的计算能力看来,进行暴力破解的成功机率还是非常大的。

建议:

  • 密码位数不宜过短;
  • 密码采用数字 + 大小写 + 特殊符号组成;
  • 不要使用一些简单的、他人也可能使用的密码组合。

3.4 加盐后的不可逆加密泄露

如果不可逆加密都如此不可靠,还有没有什么解决方案呢?当然是有的,那就是加盐后的不可逆加密。什么是加盐呢?在理解这个概念前,让我们先回过头去看一下,为什么说不可逆加密依然不可靠。原因主要有两点:

  1. 同样的密码加密后生成的密文是一样的,而一些简单密码的使用频率很高;
  2. 由于计算能力的提升,使用暴力破解的成本越来越低,使得运用彩虹表进行暴力破解的成功概率上升。

要解决这两个问题,实际上需要解决的核心是,让加密后的密文与原密码进一步隔离,这就需要加盐了。例如最常用的组合 SHA512+SALT,这里的 SALT 就是我们所说的盐,当用户注册时,先进行一次不可逆加密后,再对生成的密文撒上一点盐,就是随机值,这个撒盐的过程可以是添加前后缀,可以是改变顺序,或者某种随机的规则,并在此加了盐的密文的基础上,再进行一次不可逆加密,就大功告成了。

举个例子来说,我们先把密码 123456 不可逆加密到 abcdefg,然后对生成的密文加一些盐,比如增加前后缀变成 xxxabcefgyyy,这时再对 xxxabcefgyyy 进行一次不可逆加密生成了二次密文 3kda3kd,这时候即使数据库泄露,黑客也很难通过之前的彩虹表或大数定理的情况,反推出用户的密码了。

建议:看来真正的安全,还是要靠厂商靠谱,基本上国内外的大厂的加密都会采用类似比这种方案更加复杂一些的方案。

设置密码时,牢记这几点

如果你有耐心看完了上面这一节,一定已经理解了,密码安全其实是一个「端到端」,即「客户端 - 传输层 - 服务端」三位一体的问题,只要其中某一个环节有问题,哪怕另外两个环节做得再好再安全,也是白搭。木桶理论在安全领域,实在是再适用不过了。

我们能做好的最重要的事情,其实用一句话来概括,就是永远只在可信的设备和可信的网络环境下进行密码操作。一旦到达服务器端,基本事情就已经不在我们掌控的范围内了。一家使用明文存储密码的公司一旦发生数据泄露,哪怕我们的密码设计得再复杂,设备和网络安全再周密,这一切也都是白搭。

不过,即使是这样,我们还是有一些措施,即使在服务器端发生问题时,最小化我们的损失。

1. 密码位数、大小写和特殊符号

密码越复杂,安全程度越高,这一假设的前提是你的本地设备和网络环境足够安全,否则就像我们前面所说的,密码再复杂,如果你本地有木马程序监听输入,那么一样是徒劳。

在保证本机和网络环境安全的前提下,如果网站的数据发生泄露,对方在暴力破解时,密码的复杂程度就直接对破解的效率和成本有关系,一般来说,位数越长,混杂得大小写和特殊符号越多,暴力破解的成本就越大。所以一定杜绝使用常见的、简单的密码,建议大家的密码尽量保持在 14 位以上、存在大小写字母和数字、并混杂有特殊符号(理论上特殊符号当然是越不常见的越好,甚至有人用 emoji 作为密码中的特殊符号)。

2. 在密码中加入网站特征值

如果最坏的情况发生了,密码泄露并被破解了,怎么才能不影响自己在其它平台的账号安全?当然是不同平台和网站有不同的密码是最安全的了,这样泄露的账号和密码不会直接影响到其它平台。不过考虑到实际情况,我们很难在每一个不同的平台上都更换一个新的账号和密码,要记住不是一件容易事。这时就可以考虑一个非常简单的策略:使用一个通用的基础密码,针对不同的网站,在前后或中间插入对应该网站的一个特殊值。比如我给自己设定的一个基础密码是 Jackson%!1128,那么当我在不同的平台注册时,可以加入不一样的后缀,例如注册百度时可以有 Jackson%!1128@baidu,注册少数派时则是 Jackson%!1128@sspai,以此类推。

好处是什么呢?首先显然如果你不打算借助一些密码管理工具,而使用脑子来记密码,又希望各个平台的密码有所不同时,这是一个简单可行的方法。其次,一旦你的密码被泄露了,你还很快能追查出到底泄露源是哪。你可能会觉得黑客会不会很聪明,知道在不同网站去替换我的后缀呢?这其实很难,首次加入了这些网站特征值后本身对破解造成了难度上的提升,而从另一个方面来说,黑客基本很少会关心茫茫密码中的个人,他既没兴趣也没精力来专门针对你进行一些特殊处理。如果还是不放心的话,可以考虑在这个策略上,再加入一些变化,比如我就不会直接使用 sspai,baidu 这样的网站特征值,而是使用这些网站名称的五笔首字母,例如 baidu 就是 dy,少数派则是 ioi。

3. 直接生成随机字符串

不知道到底设什么样的密码好?其实还有一个很简单的办法,像 Safari、Chrome 等浏览器就会在页面注册账号时智能地提供一个随机字符串作为密码选项。

好处就是,完全忘掉之前说的怎么设置一个复杂的密码规则,你只需要让浏览器自动生成就可以了。不过缺点也很明显,如果你在不同的平台上登录,是 Web 环境的话需要保证全平台统一同步,而如果注册的是某些 App 使用的账号,那么登录的时候就非常不友好了。

4. 两步验证

最糟糕的情况就是密码还是泄露了,这时候有没有补救措施?当然也有,像现在大型的互联网公司一般都提供了两步验证服务,如微软、Google、苹果、印象笔记等等。一旦开启了两步验证,只要是在非授信的设置上登录,除了常规的账号和密码外,网站还会要求你额外提供绑定手机的动态验证码,这样就确保了即使的密码泄露了,依然还有一道安全屏障阻碍黑客最终登录你的账号,保护你的数据财产安全。

关于两步验证的具体教程和使用方法,可以参见:

5. 定期更改密码

这可能是听起来最简单的一件事情,但一定要做。前面提到了密码泄露的各个环节,有的是你可控的,有的是你不可控的,有的甚至是你自以为可控但其实并不可控的。对于许多人来说,我们缺乏判断本机或网络传输是否真的安全的能力,甚至像爆发的 XcodeGhost 事件,即使对于安全意识再高的人,也想不到会有这样的事情发生。

正所谓防患于未然,既然我们永远不知道水有多深,不如养成定期改密码的好习惯。

6. 永远假设你的密码会泄露

不过,一个更残酷的现实是:道高一尺,魔高一丈。网络中永远潜伏着我们还未意识到的安全风险,随时可能爆发的黑天鹅事件。

因此你在使用任何网络服务时一定要有一个意识,做好最坏的打算:永久假设你的密码一定会泄露,只是时间早晚问题。那么,这件事一旦发生后,被泄露的数据会对你造成致命的打击吗?会让你的银行卡变成人尽可取吗?会让你的身体变成人尽可看吗?会让你的阴谋变得人尽可知吗?想想这些,你还敢把银行卡密码记在短信里吗?还敢和冠希哥合拍小视频吗?还敢传政府机密文件到网盘里吗?

用工具管理密码

如果你针对不同网站设置了不同的密码,这些密码可能是之前提到的按一定规则组成的密码,也可能是完全没有任何内在逻辑、随机生成的字符。想要记住这些密码不是一件容易事,还好有许多第三方密码管理工具可以帮助我们记住这些密码,并方便地跨平台使用。

这些密码管理软件的思路都比较一致,你可以往其中添加记录许许多多的密码,在这些密码之上,会有一个主密码,只有掌握了这个主密码,你就能解锁访问其中存储的所有密码。当然这也是这类软件最为被诟病的地方之一,因为任何人只要掌握了这个主密码,都可以访问你的所有密码。这就是安全领域常说的单点突破,这让你的整个密码管理有了最薄弱的那一个环节:主密码。

当然,这些工具本身也提供了诸如生成随机密码、自动填充等实用的特性。如果你有信心,保证主密码只有天知地知你知,这一类的软件还是有用武之地的。我们就介绍一下最常见、最流行的几款热门密码管理软件吧。

1. KeePass:开源、免费、本地

KeePass 是一款开源的本地密码管理软件,采用了 AES 和 Twofish 算法的加密,其官方版本覆盖了主流的台式机平台,有 Windows/OS X/Linux 版本。由于其是开源软件,也有一些人在其基础上制作了 iOS/Android/Windows Phone 版本可以下载使用。

它最大的特点就是完全是一款本地服务,不需要联网,不需要同步,甚至不需要安装,KeePass 可以直接解压使用,非常方便直接插上 U 盘在不同的电脑上使用。

如果想在移动端也使用 KeePass,可以查看少数派之前一篇文章中的介绍,有针对 iOS/Android/Windows Phone 三大移动平台做了专门的补充。

2. iCloud Keychain:苹果生态链中的密码守护者

iCloud 钥匙串是苹果提供的基于 iCloud 的密码管理服务,其主密码自然就是你的 iCloud 或系统账号。使用 iCloud 钥匙串服务,你可以在 iPhone、iPad 及 Mac 间无缝同步你的浏览器保存密码、信用卡信息、WiFi 连接密码、应用程序密码等等。

你可以为 iCloud 钥匙串设置一个独立的安全码,当你在其它移动设备上想要访问所有的密码时,除了登录 iCloud 账号外,还需要额外验证安全码,以确保密码的安全。毕竟生活中有时候借别人的手机登一下自己的 iCloud 账号还是很经常的事情。安全码还会要求手机号短信验证,和两步验证的概念很像,如果你习惯了使用整个苹果生态链的产品,iCloud Keychain 可能是你最方便的选择。

3. 1Password:密码管理中的老牌王者

要是说起最有名的跨平台密码管理软件,大家最应该听说过的就是 1Password 了。它支持所有主流的平台,包括 Windows/Mac/iOS/watchOS/Android。最关键的是,1Password 还是最有设计感的一款密码管理软件,实际上这些密码管理软件在实现的技术方式上差别不大,基本都是 AES 加密,但 1Password 却是其中做得最精致、最细节、最具有美感的一家。

在 iOS 8 之前,1Password 在 iOS 平台上还是一款收费软件,而且由于限制,它不得不自带集成浏览器,以实现填充密码登录。不过这一切现在都变了,1Password 不仅在 iOS 平台上免费了,而且得益于分享插件的引入,现在你可以直接在 Safari 甚至任何支持的第三方 App 中,使用 1Password 填充密码。

1Password 不仅仅是保存密码,除了生成随机密码这些常用的功能外,它还有一系列丰富的管理功能。例如可以针对不同的使用者设立不同的密码仓库,可以通过文件夹、标签的形式管理密码,还能存储银行账号、护照、授权码等一系列重要的数据资料。

不过,如果你想在传统的台式设备上使用 1Password,那么就需要大手笔买买买了。其 Mac 版本和 Windows 版本售价高达 328 元,如果双版同时打包购买,也需要约 460 元。

最近 1Password 还推出了团队版,在团队协作时帮助你将一些密码分享给团队成员或同事,目前这个新版本正在 Beta 测试中,可访问官网了解详情。

想要了解更多关于 1Password 的信息,可以阅读少数派之前的文章:

4. LastPass:足够好用的替代品

如果你想要 KeePass 那样的免费,却又希望有官方提供的原生跨平台体验,你可以试试 LastPass。从功能上来说,其核心功能和 1Password 差别不大,除了颜值略低。LastPass 提供了 Mac/PC/Linux 的客户端,并在所有主流浏览器中都有插件可以安装,自然也支持当前最主流的移动平台。

在之前,LastPass 的浏览器插件及桌面端是完全免费的,但如果需要使用移动端,则要交 12 美元的年费,今年 8 月它更改了收费策略,你可以在任一平台免费使用 LastPass,但如果你需要在桌面端和移动端同步数据,或者在 iPhone 上使用 Touch ID,则需要额外交纳年费。

今年 10 月,一家专注于远程控制的科技公司 LogMeIn 宣布以 1.25 亿美元的价格,收购了 LastPass,虽然官方表示不影响 LastPass 的商业运作,但这毕竟是一次人才收购,其未来命运到底如何还很难知晓。另外需要注意的是,LastPass 曾发生过多次核心数据库泄露事件,不过似乎并没有造成实质性的损害,因为这些泄露的数据仍然是加密的。

5. 花密:本地也可以撒点盐

从密码管理工具的角度上来说,花密可能是一款很另类的软件,它不像之前介绍的 KeePass、1Password 之类的是由一个主密码加密存储了所有的个人密码。相反,它和我们之前说的在服务器端存储密码时的撒点盐很类似。

前面我们也提到了利用浏览器或第三方的密码管理工具,可以随机生成一些无规律的字符串作为密码。不过,这些密码的缺点就在于不便于建议,如果是桌面端生成的密码,在手机上要进行登录操作实在是太痛苦了。花密就解决了这样一个问题:你仍然只需要记住一个密码,花密会自动根据网站帮你最方便记忆的密码撒点盐,二次生成一个随机密码。

这样,方便你记忆的同时,也确保了密码的复杂性,同时还做到了一站一密。花密的实现其实很简单,如果有一定基础,你完全可以自己实现一个类似的算法工具。当然,花密也提供了网页版、Mac、Windows、iOS、Android 及 Chrome 浏览器插件,方便你直接使用。


希望看完本文,你能更好地了解密码到底是如何泄露的,并做好对应的防范措施,合理地使用各类密码管理工具来帮助你。最重要的事情,还是一定要假设你的密码迟早会泄露,永远去假设密码泄露后的这个信息一旦在网络上扩散,会对你有什么影响。

如果大家还有什么密码安全方面的心得或经验教训,也欢迎在评论中或微博上与我们交流分享。