阿里云
阿里云多端小程序中小企业获客首选
发表主题 回复主题
  • 11371阅读
  • 3回复

[网络/安全]如何安全的存储用户的密码一:常见攻击方法

级别: 分析狮
发帖
1559
云币
5022
— 本帖被 随歌 设置为精华(2014-07-02) —
大多数的web开发者都会遇到设计用户账号系统的需求。账号系统最重要的一个方面就是如何保护用户的密码。一些大公司的用户数据库泄露事件也时有发生,所以我们必须采取一些措施来保护用户的密码,即使网站被攻破的情况下也不会造成较大的危害。如果你还在存储用户密码的MD5,那可真的有点弱了。赶紧来看看这篇文章吧。 ~r{5`;c  
保护密码最好的的方式就是使用带盐的密码hash(salted password  hashing).对密码进行hash操作是一件很简单的事情,但是很多人都犯了错。接下来我希望可以详细的阐述如何恰当的对密码进行hash,以及为什么要这样做。 .qA{xbu  
重要提醒 P_u|-~|\  
如果你打算自己写一段代码来进行密码hash,那么赶紧停下吧。这样太容易犯错了。这个提醒适用于每一个人,不要自己写密码的hash算法  !关于保存密码的问题已经有了成熟的方案,那就是使用phpass或者本文提供的源码。 3zT_^;:L  
什么是hash `m.eM  
hash("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 G4 G5PXi  
hash("hbllo") = 58756879c05c68dfac9866712fad6a93f8146f337a69afe7dd238f3364946366 =_]2&(?  
hash("waltz") = c0e81794384491161f1777c232bc6bd9ec38f616560b120fda8e90f383853542
RwVaZJe)l  
Qo =Kqv  
Hash算法是一种单向的函数。它可以把任意数量的数据转换成固定长度的“指纹”,这个过程是不可逆的。而且只要输入发生改变,哪怕只有一个bit,输出的hash值也会有很大不同。这种特性恰好合适用来用来保存密码。因为我们希望使用一种不可逆的算法来加密保存的密码,同时又需要在用户登陆的时候验证密码是否正确。 IcIOC8WC  
在一个使用hash的账号系统中,用户注册和认证的大致流程如下: _j>;ipTb+  
1, 用户创建自己的账号 C!C|\$)-  
2, 用户密码经过hash操作之后存储在数据库中。没有任何明文的密码存储在服务器的硬盘上。 B cj/y4"  
3, 用户登陆的时候,将用户输入的密码进行hash操作后与数据库里保存的密码hash值进行对比。 !6}O.Nu  
4, 如果hash值完全一样,则认为用户输入的密码是正确的。否则就认为用户输入了无效的密码。 vEQ<A<[Z  
5, 每次用户尝试登陆的时候就重复步骤3和步骤4
YwcPX`eg  
在步骤4的时候不要告诉用户是账号还是密码错了。只需要显示一个通用的提示,比如账号或密码不正确就可以了。这样可以防止攻击者枚举有效的用户名。 gh6d&ucQ^  
还需要注意的是用来保护密码的hash函数跟数据结构课上见过的hash函数不完全一样。比如实现hash表的hash函数设计的目的是快速,但是不够安全。只有加密hash函数(cryptographic  hashfunctions)可以用来进行密码的hash。这样的函数有SHA256, SHA512, RipeMD, WHIRLPOOL等。 U.T|   
一个常见的观念就是密码经过hash之后存储就安全了。这显然是不正确的。有很多方式可以快速的从hash恢复明文的密码。还记得那些md5破解网站吧,只需要提交一个hash,不到一秒钟就能知道结果。显然,单纯的对密码进行hash还是远远达不到我们的安全需求。下一部分先讨论一下破解密码hash,获取明文常见的手段。 [\R>Xcu>  
如何破解hash u-"c0@  
字典和暴力破解攻击(Dictionary and Brute Force Attacks) c<#<k}y  
最常见的破解hash手段就是猜测密码。然后对每一个可能的密码进行hash,对比需要破解的hash和猜测的密码hash值,如果两个值一样,那么之前猜测的密码就是正确的密码明文。猜测密码攻击常用的方式就是字典攻击和暴力攻击。 YRlDX:oX~  
Dictionary Attack wNE$6  
Trying apple : failed n-QJ;37\  
Trying blueberry : failed yg]2erR  
Trying justinbeiber : failed YDmWN#  
...Trying letmein : failed m=qOg>k  
Trying s3cr3t : success!
<5@PWrU?[[  
_~aG|mAj  
3z;_KmM  
字典攻击是将常用的密码,单词,短语和其他可能用来做密码的字符串放到一个文件中,然后对文件中的每一个词进行hash,将这些hash与需要破解的密码hash比较。这种方式的成功率取决于密码字典的大小以及字典的是否合适。 B pLEPuu30  
Brute Force Attack @6o]chJo  
Trying aaaa : failedTrying aaab : failed a <X0e>  
Trying aaac : failed T}7uew\v0<  
... %~*jae!f  
Trying acdb : failed .I$}KE)  
Trying acdc : success!
暴力攻击就是对于给定的密码长度,尝试每一种可能的字符组合。这种方式需要花费大量的计算机时间。但是理论上只要时间足够,最后密码一定能够破解出来。只是如果密码太长,破解花费的时间就会大到无法承受。 #~qAHJ<  
目前没有方式可以阻止字典攻击和暴力攻击。只能想办法让它们变的低效。如果你的密码hash系统设计的是安全的,那么破解hash唯一的方式就是进行字典或者暴力攻击了。 j;K#]  
查表破解(Lookup Tables) xn}BB}s{t  
对于特定的hash类型,如果需要破解大量hash的话,查表是一种非常有效而且快速的方式。它的理念就是预先计算(pre-compute)出密码字典中每一个密码的hash。然后把hash和对应的密码保存在一个表里。一个设计良好的查询表结构,即使存储了数十亿个hash,每秒钟仍然可以查询成百上千个hash。 q;AT>" =)  
TJ6#P<M  
彩虹表 (Rainbow Tables) `"k9wC1  
彩虹表是一种使用空间换取时间的技术。跟查表破解很相似。只是它牺牲了一些破解时间来达到更小的存储空间的目的。因为彩虹表使用的存储空间更小,所以单位空间就可以存储更多的hash。彩虹表已经能够破解8位长度的任意md5hash。彩虹表具体的原理可以参考http://www.project-rainbowcrack.com/ 1K|@ h&@  
下一章节我们会讨论一种叫做“盐”(salting)的技术。通过这种技术可以让查表和彩虹表的方式无法破解hash。 . gZZCf&?  
加盐(Adding Salt) =?0QqCjK)  
hash("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824  [~Hg}-c  
hash("hello" + "QxLUF1bgIAdeQX") = 9e209040c863f84a31e719795b2577523954739fe5ed3b58a75cff2127075ed1 <rK=9"$y(t  
hash("hello" + "bv5PehSMfV11Cd") = d1d3ec2e6f20fd420d50e2642992841d8338a314b8ea157c9e18477aaef226ab dGgP_ S  
hash("hello" + "YYLmfY6IehjZMQ") = a49670c3c18b9e079b9cfaf51634f563dc8ae3070db2c4a8544305df1b60f007
7el<5chZ  
>R,?hWT  
]@xL=%   
查表和彩虹表的方式之所以有效是因为每一个密码的都是通过同样的方式来进行hash的。如果两个用户使用了同样的密码,那么一定他们的密码hash也一定相同。我们可以通过让每一个hash随机化,同一个密码hash两次,得到的不同的hash来避免这种攻击。 :X .,  
具体的操作就是给密码加一个随即的前缀或者后缀,然后再进行hash。这个随即的后缀或者前缀成为“盐”。正如上面给出的例子一样,通过加盐,相同的密码每次hash都是完全不一样的字符串了。检查用户输入的密码是否正确的时候,我们也还需要这个盐,所以盐一般都是跟hash一起保存在数据库里,或者作为hash字符串的一部分。 ]"x\=A  
盐不需要保密,只要盐是随机的话,查表,彩虹表都会失效。因为攻击者无法事先知道盐是什么,也就没有办法预先计算出查询表和彩虹表。如果每个用户都是使用了不同的盐,那么反向查表攻击也没法成功。 @Hr+/52B  
W7G9Kx1Y  
附Php,Java,C#的Hash代码: DOL%'k?B  
H)JS0 G0  
jv}=&d  
如何安全的存储用户密码二:加密源代码(php) 5A_4\YpDR  
! gp}U#Yv  
]O!s 'lC  
1 ycc5=.  
如何安全的存储用户密码三:hash源代码(java) k7bl'zic  
P%o44|[][  
IbdM9qo7  
E5x]zXy4  
如何安全的存储用户的密码四:hash源代码(c#) x% XT2+  
WL~`u  
{Jx7_T&  
本帖最近评分记录: 1 条评分 云币 +10
随歌 云币 +10 您的帖子很精彩!希望很快能再分享您的下一帖! 2014-07-02
发帖
276
云币
669
只看该作者 沙发  发表于: 2014-07-02
很赞啊,账号系统被更改也是很常见的情况。 u_'nOle K  
ze"~Ird  
感谢分享
阿里云学院免费为讲师开通视频制作环境,需要的请与我联系!
级别: 分析狮
发帖
1559
云币
5022
只看该作者 板凳  发表于: 2014-07-02
回 1楼(随歌) 的帖子
发帖
276
云币
669
只看该作者 地板  发表于: 2014-07-11
被攻击其实还比较常见,因为我最近也遇到几次类似的事情。 8dr0 DF$c  
sXSj OUI  
学习博主帖子后从容化解啊 ╮(╯▽╰)╭
阿里云学院免费为讲师开通视频制作环境,需要的请与我联系!
发表主题 回复主题
« 返回列表上一主题下一主题

限100 字节
如果您在写长篇帖子又不马上发表,建议存为草稿
 
验证问题: 99 - 6 = ?
上一个 下一个
      ×
      全新阿里云开发者社区, 去探索开发者的新世界吧!
      一站式的体验,更多的精彩!
      通过下面领域大门,一起探索新的技术世界吧~ (点击图标进入)