2011年安全界最大的新闻莫过于CSDN 600万用户账号密码泄露,CSDN后来说程序员居然使用了明文保存用户密码,导致被黑客窃取。
所以,正常的程序员都不会傻傻的选择明文保存用户密码,他会说:用Hash啊!不过,保存密码的Hash值真的就安全了吗?阿呆要告诉你,如果只是保存Hash值,可能并不比明文保存安全多少,对于很多常用密码,黑客估计费不了多少时间就能破解。
密码Hash
所谓密码Hash就是用一种不可逆的算法,把密码搞成一堆乱码。如下图。
所以,用户密码的验证流程是:
- 用户创建账户,设置密码,或者修改密码;
- 程序把密码用Hash算法弄成乱码保存到硬盘,这样除了用户自己谁也不知道密码是什么;
-
用户再次登录的时候,要输密码,程序把新输的密码算Hash值和保存在硬盘里的Hash值比对,相同就通过,不相同就拒绝访问;
这里说的Hash算法可不是我们数据结构课程里教的那些了,密码Hash算法是要满足很多条件的。比如离散型要够好,密码即使小差别,Hash值却是完全不同。目前密码专家开发出了很多这种算法,比如MD5、SHA256等等。
不过,下面,大神就要告诉你怎么轻松破解Hash值保存的密码了。
破解Hash过的密码大法揭秘
既然明文密码有可能泄露,那么密码Hash值也是有可能泄露的,如果黑客拿到了Hash值后,会如何破解呢?
- 词典法:用各种词典里的单词组合去一个个尝试,适合用单词组成的密码。所以不要用单词做密码!
- Brute Force法:用各种字母的组合去尝试,适合短密码。所以不要设置短密码!
-
查找表法:预先算好各种常见密码的MD5,SHA256等标准算法Hash值,保存Hash值到密码的查找表,建立搜索索引表。获得Hash值后花个几秒钟直接来搜一下就很快找到原始密码了。比如CSDN 600万密码必然已经进入了黑客的查找表了,如果你的密码和这600万中任何一个一样,就有被轻松破解的风险。所以不要设置和已经公开的任何密码相同的密码!每个网站账户使用不同密码!
-
反向查找表法:如果已经破解了数据库,获得了各种密码的Hash值,要想获得原始密码,可用此法批量操作。方法就是,首先建立Hash值到用户名的查找表,然后用各种常用密码的Hash去这个表里查,相同就说明对应用户的密码是这个。
- 彩虹表法:比较复杂,阿呆也没来得及研究。不过令人恐怖的是,彩虹表法能够破解MD5 Hash保存的所有8字符以内密码。所以密码不要短于8个字符!
给Hash加点盐
现实真令人忧桑:保存密码Hash值没想到这么脆弱。那该怎么办?加点盐Salt来消消毒就好了。
如下图,Salt是一个随机字符串,每次密码Hash的时候,加一个随机产生的和Hash值一样长的Salt一起算,这样即使密码一样,Hash值也完全不同。前面的各种方法无效,黑客就只能哀嚎了!
那万一Salt忘了该怎么办?其实Salt并不是要记在脑子里,只要和Hash值一起保存就可以了。验证密码的时候使用Salt和Hash一起操作。
切记Salt有几个注意事项:
- Salt不能重复使用:每次新建账户或修改密码时随机产生,避免相同密码产生相同Hash值。
- Salt不能太短:如果很短,黑客就可以针对各种可能的Salt建立查找表。比如Salt只有3个字符,那就有95x95x95=857,375中可能性,如果一共有1MB的常用密码查找表,那这么多Salt才占用了837GB(857,375/1024),装不满一个硬盘。另外,也不能直接拿用户名做Salt,增加了和其他网站的重复性,因为很多用户不同网站采用同一个用户名。
- Salt不能用普通的随机数生成器产生:Salt需要用密码学专用的算法CSPRNG产生,既保证随机性,又有不可预测性。普通的随机数生成器其实是个多项式,很容易被人猜出来。
多重Hash有用吗?
有些人觉得各种MD5,SHA256等各种Hash重复算几次更加安全,比如下面:
- md5(sha1(password))
- md5(md5(salt) + md5(password))
- sha1(sha1(password))
- sha1(str_rot13(password + salt))
- md5(sha1(md5(md5(password) + sha1(password)) + md5(password)))
其实这样反而更不安全。永远不要用自创的Hash算法!因为,各种标准的密码Hash算法都是专家经过数学推理和实践验证得到的,比自己搞的强太多了。而不同Hash叠加使用,会带来最初设计意想不到的叠加效应,反而降低了安全性。想想就知道了,如果这么做有用,为什么密码专家不直接合起来发布一个新算法呢?
选什么Hash算法比较合适?
使用了Salt之后,可以防止通过Hash查出密码这种破解法。但是,对于用各种单词和字母组合去猜密码是没办法的。对这种暴力方法,就要以暴易暴,使用计算量很大的Hash算法,让破解进程异常缓慢。这种代表算法是PBKDF2、bcrypt等,这些算法用一个参数来让用户定义计算量。一般算个半秒比较正常。
不过计算量变大,意味着服务器压力变大了。假如有人搞个DoS攻击,服务器瞬间瘫痪了。所以,最好输入密码的时候,要求输入验证码,比如说对计算机来说自动识别比较难的验证码算法CAPTCHA。
终极方案——高性能硬件加密存储
只要黑客有机会通过Hash比对来验证密码,他就能一遍遍的尝试,最终有可能找到密码。同时,如果一切都是软件算法,那么,黑客总是有办法找到漏洞,攻破一道道防线,获得关键数据,比如说拿到所有用户的Hash值。
所以,保证安全的最好方式就是物理隔离,对Hash值等关键数据加密并存储在加密存储设备上。用户验证密码,必须输入Hash值的保护密码,或者获得U盾等硬件设备的授权。黑客即使破解了系统,没有加密存储密码或者U盾,也无能为力。
对于企业应用来说,关键数据的用户量很多,性能要求高,传统机械硬盘就带宽和IOPS不够了,需要使用SSD来存储。不过,目前有加密功能的SSD几乎没有,符合国家加密标准的更是凤毛麟角。很多是SSD配一个加密卡,性能和延迟都很差。
阿呆所在的方一信息科技有高性能加密存储PCIe SSD,数据实时硬件加密,读写性能和正常PCIe SSD一样,符合国家加密标准,完全自主可控。有兴趣的可以微信加nanoarch为好友,和阿呆私聊。
引用: