用户密码安全存储建议

fmms 13年前
              <a name="OLE_LINK3"><span style="font-family:微软雅黑;"><span style="color:#000000;">安全小测验</span></span></a>    <span style="font-family:微软雅黑;"><span style="color:#000000;">:存储机密信息最安全的办法是什么?</span></span>    <p><span style="color:#000000;"><span style="font-family:Verdana;">            a)</span><span style="font-family:微软雅黑;">利用</span><span style="font-family:Verdana;"> 256 </span><span style="font-family:微软雅黑;">位密钥的强对称加密算法(例如</span><span style="font-family:Verdana;"> AES</span><span style="font-family:微软雅黑;">)进行加密。</span></span></p>    <p><span style="color:#000000;"><span style="font-family:Verdana;">            b)</span><span style="font-family:微软雅黑;">利用</span><span style="font-family:Verdana;"> 4096 </span><span style="font-family:微软雅黑;">位密钥的非对称强加密算法(例如</span><span style="font-family:Verdana;"> RSA</span><span style="font-family:微软雅黑;">)进行加密。</span></span></p>    <p><span style="color:#000000;"><span style="font-family:Verdana;">            c)</span><span style="font-family:微软雅黑;">利用平台内</span><span style="font-family:微软雅黑;">置的加密系统进行加密,例如</span><span style="font-family:Verdana;"> Windows </span><span style="font-family:微软雅黑;">的数据保护</span><span style="font-family:Verdana;"> API (DPAPI)</span><span style="font-family:微软雅黑;">。</span></span></p>    <p><span style="font-family:微软雅黑;"><span style="color:#000000;">       做出选择了吗?正确的答案实际上是:</span></span></p>    <p><span style="color:#000000;"><span style="font-family:Verdana;">            d)</span><span style="font-family:微软雅黑;">既然是机密数据,就完全不要存储!</span></span></p>    <p><span style="color:#000000;"><span style="font-family:微软雅黑;">       好吧,这个问题看上去有点难,但其答案是很有道理的:窃贼无法窃取根本不存在的东西。我们把这个原则应用到身份验证操作,如网站登录。如果一个网站永远不 存储用户的密码,那么即使网站受到攻击,这些密码也不能被盗走。但是网站如何在不存储用户密码的情况下来验证用户的身份呢?答案就是网站存储密码的加密哈 希,而不是明文密码本身。(如果你对哈希的概念不熟悉,我们建议你在继续前阅读</span></span><a href="/misc/goto?guid=4959517368517404725"><span style="font-family:Verdana;color:#0000ff;"><u>http://msdn.microsoft.com/zh-cn/library/92f9ye3s.aspx#hash_values</u></span></a><span style="color:#000000;"><span style="font-family:微软雅黑;">。)通过比较哈希而不是明文,网站仍然可以验证用户确实知道自己的密码,不然哈希将不会匹配,而实现这个过程并不需要网站实际存储密码(如图</span><span style="font-family:Verdana;">1</span></span><span style="font-family:微软雅黑;"><span style="color:#000000;">所示)。这是一个不错的解决方案,但是仍有一些设计方面的注意事项,以确保你不会无意间削弱系统的强度。</span></span></p>    <p><span style="color:#000000;"><span style="font-family:微软雅黑;">       第一个设计问题是,简单地对密码进行哈希计算并不能提供充分的保护:你还需要在计算哈希值前为每个密码添加随机盐值</span><span style="font-family:Verdana;">(Salt)</span><span style="font-family:微软雅黑;">。切记,对于给定的哈希函数,对某个输入值计算哈希值始终会得到相同的输出值。如果时间充裕,攻击者可能会计算出明文字符串及其相应哈希值的表。事实上,已经存在很多这样的表(称为</span><span style="font-family:Verdana;">“</span><span style="font-family:微软雅黑;">彩虹表</span><span style="font-family:Verdana;">”</span><span style="font-family:微软雅黑;">), 并且可在互联网上免费下载。有了彩虹表后,如果攻击者通过任意方式设法获取了某网站的密码哈希列表,那么他可以使用该表轻松地确定初始的明文密码。当你对 哈希加盐值时,你就可以从攻击者手中夺走这个“武器”。另外,要为每个用户生成(并存储)特定的盐值,而不是每个用户使用相同的盐值,这一点很重要。如果 你始终使用相同的盐值,则攻击者可能会构建一个使用该单一盐值的彩虹表,从而提取出密码。</span></span></p>    <p align="center"><a href="/misc/goto?guid=4959517368715740931"><img title="clip_image002[6]" border="0" alt="用户密码安全存储建议" src="https://simg.open-open.com/show/c630eb98f8fed3c2a2bd177870e588b8.jpg" width="511" height="861" /></a></p>    <p align="center"><span style="color:#000000;"><span style="font-family:微软雅黑;">图</span><span style="font-family:Verdana;"> 1</span><span style="font-family:微软雅黑;">:比较加盐值后的哈希值</span></span></p>    <p><span style="color:#000000;"><span style="font-family:微软雅黑;">       另一个重要的设计问题是,一定要使用强加密哈希算法。</span><span style="font-family:Verdana;">MD5 </span><span style="font-family:微软雅黑;">可能是比较常见的选择,但是密码学家已经论证了</span><span style="font-family:Verdana;"> MD5 </span><span style="font-family:微软雅黑;">的脆弱性,近年来它一直被认为是不安全且</span><span style="font-family:Verdana;">“</span><span style="font-family:微软雅黑;">可破解</span><span style="font-family:Verdana;">”</span><span style="font-family:微软雅黑;">的算法。</span><span style="font-family:Verdana;">SHA-1 </span><span style="font-family:微软雅黑;">安全性稍微强一些,但它也开始显现被破解的迹象,现在密码学家建议避免使用</span><span style="font-family:Verdana;"> SHA-1</span><span style="font-family:微软雅黑;">。</span><span style="font-family:Verdana;">SHA-2 </span><span style="font-family:微软雅黑;">哈希算法系列当前被视为最强健的算法,是唯一获得微软安全开发生命周期</span><span style="font-family:Verdana;"> (SDL) </span><span style="font-family:微软雅黑;">加密标准策略批准,可以在微软</span><span style="font-family:微软雅黑;">产品中使用的哈希算法系列。</span></span></p>    <p><span style="color:#000000;"><span style="font-family:微软雅黑;">       相比将</span><span style="font-family:Verdana;">SHA-2</span><span style="font-family:微软雅黑;">硬编码入程序,一个更好的办法是实施</span><span style="font-family:Verdana;"> “</span><span style="font-family:微软雅黑;">加密灵活性</span><span style="font-family:Verdana;">”</span><span style="font-family:微软雅黑;">,就是说即使应用程序已经部署到生产中,也仍然可以改变哈希算法。毕竟,加密算法会过时;密码学家会发现其弱点,并且随着计算能力的增强,使用暴力攻击破解越来越轻松可行。某一天,</span><span style="font-family:Verdana;">SHA-2 </span><span style="font-family:微软雅黑;">可能会被认为和</span><span style="font-family:Verdana;"> MD5 </span><span style="font-family:微软雅黑;">一样脆弱,未雨绸缪不失为明智的选择。对哈希灵活性进行深入分析讨论已经超出了本篇博文的讨论范围,不过,你可以在</span><span style="font-family:Verdana;"> MSDN </span><span style="font-family:微软雅黑;">杂志文章</span><span style="font-family:Verdana;">“</span><span style="font-family:微软雅黑;">加密灵活性</span><span style="font-family:Verdana;">”[</span></span><a href="/misc/goto?guid=4959517368810330689"><span style="font-family:Verdana;color:#0000ff;"><u>http://msdn.microsoft.com/zh-cn/magazine/ee321570.aspx</u></span></a><span style="color:#000000;"><span style="font-family:Verdana;">] </span><span style="font-family:微软雅黑;">中阅读了解关于建议解决办法的更多信息。就像</span><span style="font-family:Verdana;"> SDL </span><span style="font-family:微软雅黑;">强制在微软</span></span><span style="font-family:微软雅黑;"><span style="color:#000000;">产品中使用强加密算法一样,它也鼓励产品团队尽可能使用加密灵活性,这样可以在当前强算法遭到破解的情况下更敏捷地迁移到新算法。</span></span></p>    <p><span style="color:#000000;"><span style="font-family:微软雅黑;">       到目前为止,我们已经讨论了要对<em>哪些内容</em>进行哈希计算(密码和随机的特定盐值)以及<em>如何</em>进行哈希计算(使用</span><span style="font-family:Verdana;"> SHA-2 </span><span style="font-family:微软雅黑;">系列中的加密强哈希算法,最好是可配置的,以便允许进行未来变更),但是我们还没有讨论哈希计算的<em>应用位置</em>。 你可能会认为在客户端执行哈希计算将能极大地提高安全性,因为你只需要通过网络向服务器发送哈希,而绝不会发送明文密码本身。不过,好处也并不像你想象的 那么多。如果攻击者能够嗅探网络流量,他仍然可以拦截传输,并自行将哈希传递到服务器,从而欺骗用户,劫持其会话。这时,哈希本质上会成为明文密码。这个 方法唯一切实的好处就是如果受害者在多个网站上使用同一密码,则攻击者将不能在其它网站损害受害者的帐户,因为知道密码的哈希值并不会告诉你关于密码本身 的任何内容。防御此类攻击的更好方式是,在服务器端执行哈希计算,但确保密码和所有凭据令牌(例如会话</span><span style="font-family:Verdana;"> Cookie</span><span style="font-family:微软雅黑;">)始终通过</span><span style="font-family:Verdana;"> SSL/TLS </span><span style="font-family:微软雅黑;">进行传输。在将来发布的博文中,我们会讨论安全凭据传输(和密码管理的其他方面,例如密码复杂性及其过期时间)。</span></span></p>    <p><span style="font-family:微软雅黑;"><span style="color:#000000;">       遵循下面一些简单的原则,有助于你确保应用程序的用户凭据仍保持安全,即便在数据库被攻破的情况下也是如此:</span></span></p>    <p><span style="color:#000000;"><span style="font-family:Symbol;">            ·</span><span style="font-family:微软雅黑;">始终存储并比较密码的哈希,而永远不要存储明文密码本身。</span></span></p>    <p><span style="color:#000000;"><span style="font-family:Symbol;">            ·</span><span style="font-family:微软雅黑;">在进行哈希计算前,对每个密码应用随机且特定的盐值。</span></span></p>    <p><span style="color:#000000;"><span style="font-family:Symbol;">            ·</span><span style="font-family:微软雅黑;">使用加密的强哈希算法,例如</span><span style="font-family:Verdana;"> SHA-2 </span><span style="font-family:微软雅黑;">系列之一。</span></span></p>    <p><span style="color:#000000;"><span style="font-family:Symbol;">            ·</span><span style="font-family:微软雅黑;">通过实施灵活的加密设计,允许未来潜在的算法变更。</span></span></p>    <p><span style="color:#000000;"><span style="font-family:Symbol;">            ·</span><span style="font-family:微软雅黑;">对服务器层进行哈希计算,并确保通过</span><span style="font-family:Verdana;"> HTTPS </span><span style="font-family:微软雅黑;">传输所有密码和凭据令牌。</span></span></p>    <p><em>作者:Bryan Sullivan <a href="/misc/goto?guid=4959517368908133674"><img title="clip_image001" border="0" alt="用户密码安全存储建议" src="https://simg.open-open.com/show/af019fbb857023b8ac0bbd30a0e388c2.jpg" width="100" height="100" /></a></em></p>    <p><em>资深安全项目经理</em></p>    <p><em>微软SDL(安全开发生命周期)团队</em></p> 来自:    <a href="/misc/goto?guid=4959517368999282093" target="_blank">http://blog.csdn.net/mssecurity/article/details/7209481</a>