月光博客 » 编程开发 » 如何安全的存储密码

如何安全的存储密码

  过去一段时间来,众多的网站遭遇用户密码数据库泄露事件,这甚至包括顶级的互联网企业–NASDQ上市的商务社交网络Linkedin,国内诸如CSDN一类的就更多了。

  层出不穷的类似事件对用户会造成巨大的影响,因为人们往往习惯在不同网站使用相同的密码,一家“暴库”,全部遭殃。

  那么在选择密码存储方案时,容易掉入哪些陷阱,以及如何避免这些陷阱?我们将在实践中的一些心得体会记录于此,与大家分享。

如何安全的存储密码

  菜鸟方案

  直接存储用户密码的明文或者将密码加密存储。

  曾经有一次我在某知名网站重置密码,结果邮件中居然直接包含以前设置过的密码。我和客服咨询为什么直接将密码发送给用户,客服答曰:“减少用户步骤,用户体验更好”;再问“管理员是否可以直接获知我的密码”, 客服振振有词:“我们用XXX算法加密过的,不会有问题的”。 殊不知,密码加密后一定能被解密获得原始密码,因此,该网站一旦数据库泄露,所有用户的密码本身就大白于天下。

  以后看到这类网站,大家最好都绕道而走,因为一家“暴库”,全部遭殃。

  入门方案

如何安全的存储密码

  将明文密码做单向哈希后存储。

  单向哈希算法有一个特性,无法通过哈希后的摘要(digest)恢复原始数据,这也是“单向”二字的来源,这一点和所有的加密算法都不同。常用的单向哈希算法包括SHA-256,SHA-1,MD5等。例如,对密码“passwordhunter”进行SHA-256哈希后的摘要(digest)如下:
bbed833d2c7805c4bf039b140bec7e7452125a04efa9e0b296395a9b95c2d44c

  可能是“单向”二字有误导性,也可能是上面那串数字唬人,不少人误以为这种方式很可靠, 其实不然。

  单向哈希有两个特性:

  1)从同一个密码进行单向哈希,得到的总是唯一确定的摘要

  2)计算速度快。随着技术进步,尤其是显卡在高性能计算中的普及,一秒钟能够完成数十亿次单向哈希计算

  结合上面两个特点,考虑到多数人所使用的密码为常见的组合,攻击者可以将所有密码的常见组合进行单向哈希,得到一个摘要组合,然后与数据库中的摘要进行比对即可获得对应的密码。这个摘要组合也被称为rainbow table。

  更糟糕的是,一个攻击者只要建立上述的rainbow table,可以匹配所有的密码数据库。仍然等同于一家“暴库”,全部遭殃。以后要是有某家厂商宣布“我们的密码都是哈希后存储的,绝对安全”,大家对这个行为要特别警惕并表示不屑。有兴趣的朋友可以搜索下,看看哪家厂商躺着中枪了。

  进阶方案

如何安全的存储密码

  将明文密码混入“随机因素”,然后进行单向哈希后存储,也就是所谓的“Salted Hash”。

  这个方式相比上面的方案,最大的好处是针对每一个数据库中的密码,都需要建立一个完整的rainbow table进行匹配。 因为两个同样使用“passwordhunter”作为密码的账户,在数据库中存储的摘要完全不同。

  10多年以前,因为计算和内存大小的限制,这个方案还是足够安全的,因为攻击者没有足够的资源建立这么多的rainbow table。 但是,在今日,因为显卡的恐怖的并行计算能力,这种攻击已经完全可行。

  专家方案

如何安全的存储密码

  故意增加密码计算所需耗费的资源和时间,使得任何人都不可获得足够的资源建立所需的rainbow table。

  这类方案有一个特点,算法中都有个因子,用于指明计算密码摘要所需要的资源和时间,也就是计算强度。计算强度越大,攻击者建立rainbow table越困难,以至于不可继续。

  这类方案的常用算法有三种:

  1)PBKDF2(Password-Based Key Derivation Function)

  PBKDF2简单而言就是将salted hash进行多次重复计算,这个次数是可选择的。如果计算一次所需要的时间是1微秒,那么计算1百万次就需要1秒钟。假如攻击一个密码所需的rainbow table有1千万条,建立所对应的rainbow table所需要的时间就是115天。这个代价足以让大部分的攻击者忘而生畏。

  美国政府机构已经将这个方法标准化,并且用于一些政府和军方的系统。 这个方案最大的优点是标准化,实现容易同时采用了久经考验的SHA算法。

  2) bcrypt

  bcrypt是专门为密码存储而设计的算法,基于Blowfish加密算法变形而来,由Niels Provos和David Mazières发表于1999年的USENIX。

  bcrypt最大的好处是有一个参数(work factor),可用于调整计算强度,而且work factor是包括在输出的摘要中的。随着攻击者计算能力的提高,使用者可以逐步增大work factor,而且不会影响已有用户的登陆。

  bcrypt经过了很多安全专家的仔细分析,使用在以安全著称的OpenBSD中,一般认为它比PBKDF2更能承受随着计算能力加强而带来的风险。bcrypt也有广泛的函数库支持,因此我们建议使用这种方式存储密码

  3) scrypt

  scrypt是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的。

  和上述两种方案不同,scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。但是,scrypt在算法层面只要没有破绽,它的安全性应该高于PBKDF2和bcrypt。

  来源:坚果云投稿,坚果云是一款类似Dropbox的云存储服务,可以自动同步、备份文件。原文链接

如何安全的存储密码

顶一下 ▲()   踩一下 ▼()

相关文章

  1. 1
    Chon   说道:
    > 以后看到这类网站,大家最好都绕道而走,因为一家“暴库”,全部遭殃。

    能告诉我们是哪个网站, 做个黑名单吧, 好知道哪些要绕着走.
    支持(20反对(11回复
  1. 2
    可可   说道:
    我的做法是用一串毫无意义的字符加上无意义的数字加上特殊符号,例如dhirjvd1832@,并且所有账户的密码都不一样。当然,记忆是个问题,所以我将账户和密码写在小卡片上,放入钱包,随身携带。
    1 于 2012-9-18 22:48:40 回复
    钱包被偷的概率比密码破解的概率大
    支持(25反对(17回复
  1. 3
    RQCMS   说道:
    国内那些所谓的IT网站明文存储密码真是太无耻了。
    支持(19反对(12回复
  1. 4
    向日葵媒体设计   说道:
    我有几亿美金存款会考虑这种密码
    支持(24反对(17回复
  1. 5
    dove   说道:
    不管用哪个方法,总是有点不放心

    我现在是自己写了个密码管理软件,自己设置密钥进行加密,保存在xml文件中,虽然不能保证安全,但自己写的心里放心。
    支持(15反对(9回复
  1. 6
    zzz   说道:
    烂文章 彩虹表哪有那么厉害,很多密码根本猜不出来,只是常见的词语会被收录而已。
    支持(15反对(10回复
  1. 7
    有风的日子   说道:
    安全很重要,有加密就会有解密,没有决对安全。
    di风 于 2012-9-19 9:49:54 回复
    “当破解成本高于信息本身的价值,就可以认为加密是安全的”,类似的话我相信你一定听过。
    支持(18反对(14回复
  1. 8
    李子   说道:
    安全总是相对的,要不断修练。
    支持(11反对(7回复
  1. 9
    chxkyy   说道:
    进阶方案如何确认输入的密码是正确的?
    支持(17反对(14回复
  1. 10
    che   说道:
    我昨天用26个字母和N组一定数量的数字,经过N次计算之后,每个字母都得出了一个对应的密码,由一个字母和数字组成。每个字母对应的密码之间,没有任何关系。
    这样每次的登录的时候,你只要看看浏览框的网址域名就知道你要登录的密码了。
    不过蛋疼的是,要么记住那个对应表,要么随身带着……
    不过,如果知道了一定数量的密码之后,被爆菊的概率就很大了。
    支持(16反对(14回复
  1. 11
    google315   说道:
    对于上文我想听听王小云看法。
    支持(14反对(12回复
  1. 12
    坪山钟爱一生   说道:
    值得学习,虽然领悟慢了,还能学得会..
    支持(14反对(12回复
  1. 13
    蔚蓝海岸   说道:
    安全很重要,希望大家的安全意识越来越强
    支持(18反对(17回复
  1. 14
    蓝天白云   说道:
    保存密码用keepassx呗。
    支持(13反对(12回复
  1. 15
    vino   说道:
    没那么麻烦 我觉得 ,自己做到密码分级才是重要的 ,一般网站 ,就自己设置稍微简单的密码,有关隐私的 设置复杂点的密码,有关MONEY的,设置高难度的一个密码。
    只要做到这点,就可以啦。
    至于社交网站,就设置成中高难度的密码。
    三个不同密码,畅游网络。
    支持(14反对(13回复
  1. 16
    overmind   说道:
    lastpass吧,虽然存在那边数据库被黑一锅端的风险,问题是,如何从这数千万的账户密码中找到有价值的呢
    支持(13反对(13回复
  1. 17
    不锈钢合页   说道:
    很好的文章,写的太好了,学到了很多!
    支持(13反对(15回复
  1. 18
      说道:
    扯淡。
    如果只是单纯的增加算法强度,那么当大量用户同时请求验证密码的时候,服务器的压力可想而知。增强算法强度只是其中一条路,而加salt的性价比更高。晕死,不让发链接,有兴趣的人自己去搜下面这篇文章吧。
    《How To Safely Store A Password》
    支持(11反对(14回复
  1. 19
    nobush   说道:
    一串數字的計算總會有極限,是否考慮多維的密碼,立體破解就不大可能了。
    支持(9反对(12回复
  1. 20
    拓荒   说道:
    文章我都看不懂,要努力学习啦!
    支持(11反对(15回复
  1. 21
    老Q   说道:
    尤其是显卡在高性能计算中的普及,一秒钟能够完成数十亿次单向哈希计算---------神马显卡??
    支持(8反对(13回复
  1. 22
    可可   说道:
    当然了,我这里说的是用户保存密码的方法。是另外一个主题。
    支持(12反对(18回复

发表留言