
无论是开发应用程序还是网站,只要有用户登录会话,就会涉及如何存储用户密码的问题. 如果用于存储密码的技术不够安全,那么一旦黑客闯入存储密码的,黑客就可以获得用户的密码,并可能给用户造成重大损失. 在这种情况下,没有公司愿意发生这种情况,因此有必要选择一种安全地存储密码的策略.
最简单的存储密码的方法不是自己存储,而是将其委托给受信任的第三方来存储. 这是OpenID技术,其概念是使用第三方来完成用户验证操作. 目前,国外网站(如Google,Yahoo等)和国内网站(如腾讯)已经提供OpenID服务. 如果我们开发网站并选择Google的OpenID服务,则用户可以使用其Gmail帐户和密码登录,下一次用户身份验证将由Google完成.
采用OpenID技术对网站的开发人员和用户都具有明显的优势. 由于用户的登录身份验证是由第三方OpenID服务提供商完成的,因此我们不需要自己存储用户名和密码,也不需要考虑存储密码的安全性,从而降低了开发成本. 同时,用户无需在我们的网站上注册新的用户名和密码. 这样不仅为用户省去了在注册用户名和密码时填写信息的麻烦,而且减轻了用户需要记住新的一对用户名和密码的负担.

许多公司出于各种原因不愿将客户的登录信息保留在其他公司中,因此他们必须存储自己的密码. 现在,您决定自己存储它,您必须考虑存储的安全性. 密码存储的最低要求是密码不能以明文形式存储(未加密). 如果密码以纯文本格式存储,一旦泄漏,所有用户的密码将毫无保留地暴露给黑客,这可能给用户和公司造成巨大损失.
尽管不能以纯文本形式存储密码的原因很明显存储安全,但是仍然有许多公司使用这种极为不安全的方法. 从不时爆发的各种网站的密码泄漏中可以看出. 对于仍仍以纯文本形式存储密码的公司,我们只能建议他们在存储密码之前尽快使用哈希算法对密码进行加密.
常用的密码加密算法是几种单向哈希算法. 所谓的单向算法意味着我们只能从纯文本中生成相应的哈希值,而不能再根据哈希值获得相应的纯文本. 每个人都常用的加密算法是MD5和SHA系列(例如SHA1,SHA256,SHA384,SHA512等). 值得注意的是,中国数学家王小云破解了MD5算法,因此不再推荐在产品中使用.

尽管使用哈希算法可以提高密码存储的安全性,但仍然不够安全. 通常,在黑客入侵存储密码的之后,他会随机猜测密码并使用哈希算法生成哈希值. 如果哈希值存在于中,则他猜到了用户的密码. 如果没有猜测,没关系,他可以随机地猜测下一个密码再尝试. 实际上,为了提高破解密码的效率,黑客会预先计算与大量密码相对应的各种哈希算法的哈希值,并将密码和相应的哈希值存储在表格中(此表格通常称为Rainbow表). 破解密码时,只需在预先准备好的彩虹表中进行匹配即可. 因此,现在,黑客实际上已经破解了仅使用哈希算法加密的密码,这实际上是毫不费力的.
为了处理使用Rainbow表破解密码的黑客,我们可以先在默认文本密码中添加salt,然后再使用哈希算法对salted密码进行加密. 所谓的盐是一个随机的字符串. 在纯文本密码中加盐是将纯文本密码与随机字符串连接在一起. 由于salt仍用于密码验证,因此通常salt和password的哈希值会存储在一起.
值得注意的是,使用盐腌哈希算法来加密密码. 我们要确保为每个密码添加随机且唯一的盐,而不是让所有密码共享相同的盐. 如果所有密码共享一个统一的盐,那么当黑客猜测盐时,他可以为盐生成一个彩虹表,然后将盐添加到新的彩虹表中以匹配哈希值以破解密码.

虽然加盐算法可以有效地处理彩虹表破解方法,但是其安全级别不高,这是由哈希算法的特性引起的. 哈希算法最初用于确保通过网络传输数据时的数据完整性. 当我们通过网络传输数据包时,在发送时,我们将在数据包的末尾附加与该数据包相对应的哈希值. 接收数据时,我们再次使用相同的算法根据接收到的数据包生成哈希值. 如果哈希值与从网络接收的哈希值相同,则证明数据传输没有问题. 为了减少网络传输的延迟,我们希望哈希算法尽可能快,并且尽可能减少数据验证时间. 因此,在设计哈希算法时,快速高效是非常重要的指标. 目前,在具有通用配置的计算机上,主流哈希算法花费的时间为微秒级,这意味着我们可以在一秒钟左右的时间内计算出近一百万次的哈希值.
快速高效的哈希算法给加密算法带来了很多挑战,因为安全加密算法对于黑客来说应该是一个极其困难的算法,并且哈希值的计算需要很短的时间,并且黑客可以使用加盐后,使用蛮力方法破解使用哈希算法加密的密码. 如前所述,盐通常与哈希值一起存储. 因此,黑客可以使用两种简单的暴力破解方法来破解每种盐的密码.
首先,使用穷举法. 黑客会生成一个密码,并用salt对其进行缝合,然后计算哈希值. 如果哈希值与中的哈希值匹配,则密码被破解. 如果不一致,请继续下一个尝试. 此方法对于低级密码非常有效. 例如,一个六位数的全数字密码只能输入一百万. 这意味着即使添加盐也可以在几秒钟内破解任何6位纯数字密码. 尽管目前破解高级别密码(例如包含数字,大写和小写字母以及特殊符号的密码)的暴力破解方法需要大量时间,但根据摩尔定律,计算能力仍在不断提高,今天看来这项工作非常耗时,将来可能很快完成. 此外,近年来云计算的飞速发展也使黑客能够以非常低廉的价格租用大量计算机,以方便他们并行破解密码,从而使黑客有可能以低成本破解高级别密码. 高效地
第二,黑客从以前的密码泄露事件中收集了许多常用的密码. 对于每种盐,黑客可以循环选择这些重用密码之一,添加盐,然后计算哈希值. 因此,这些常用密码即使带盐也很容易破解.
为了处理暴力方法,我们需要非常耗时的哈希算法,而不是非常高效的哈希算法. BCrypt算法应运而生. 我们可以使用BCrypt算法添加盐并为密码生成哈希值. Bcrypt的最大特点是我们可以通过参数设置重复计算的次数. 显然,重复计算的次数越多,花费的时间就越长. 如果花一秒钟或更长时间来计算哈希值,那么黑客将不再可能使用暴利方法来破解密码. 以上述的6位纯数字密码为例,破解密码需要11.5天,更不用说安全级别高的密码了.
当前有一些实现BCrypt算法的开源项目()存储安全,并被业界广泛采用. 如果您是.NET程序员,则可能会发现当前的.NET Framework尚不包含BCrypt的实现. 有两种选择. 首先,已经有一些开源项目在C#中实现了BCrypt算法,我们可以直接使用它. 如果担心这些实现的安全性,我们还可以选择类似于BCrypt的PBKDF2. PBKDF2还可以通过参数设置重复计算的次数,以延长计算时间. 在.NET Framework中,类型Rfc2898DeriveBytes实现了PBKDF2的功能.
安全地存储密码不是一件容易的事. 尽管许多公司当前使用盐化哈希算法来处理彩虹表破解,但是这种方法不够安全. 由于哈希算法非常有效,因此哈希值的计算需要微秒,因此黑客可以通过蛮力破解密码. 推荐的方法使用BCrypt或PBKDF2来延长计算哈希值的时间,从而增加破解密码的难度. 此外,并非每个公司或项目都需要存储自己的密码. 我们的另一种选择是使用OpenID将用户验证委派给受信任的第三方公司.
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/ruanjian/article-191094-1.html
叫兽