百科问答小站 logo
百科问答小站 font logo



先用md5,再用sha1,这样密码会安全一点吗? 第1页

  

user avatar   karminski 网友的相关建议: 
      

文中关于彩虹表的描述有误,评论里比我讲得更准确:


Lu Jerry1 分钟前
关于彩虹表的描述是错误的,这是暴力穷举表,建议答主修改答案。原文“这彩虹表大概多大呢? 答案是, 10TB 的硬盘需要……”修改成“10TB 的硬盘需要一个”。





但凡看了wikipedia, 都不会弄出来这样的问题. 请用 bcrypt/Argon2的较新版本/Scrypt.


我接下来的回答主要针对有些人不明白为什么salt要足够长.


好多人不懂为啥要增加salt的长度, 尤其是 @Ivony 评论底下的.


(建议你们还是直接用相应语言的bcrypt官方demo吧.... Go的bcrypt库十分友好, 知道你不会加盐, 加盐的步骤直接在内部帮你包装好了...【手动狗头】)



我们举个理论模型, 现在用户密码是4位的大小写数字字母符号组合(26大写, 26小写, 10数字, 18符号, 总计80个), 加密方式SHA1(8 bytes), 那么彩虹表有多大呢? 是80^4 x 8bytes = 312.5MiB. SD卡都能装得下.


这时如果我们给用户密码再来个4位的跟密码一样空间的salt, 那么需要的彩虹表会是多大呢? 80^4 x 80^4 x 8bytes = 11.92 EiB 这彩虹表大概多大呢? 答案是, 10TB 的硬盘需要 1300 多块才能装得下, 假设一个 2U 机器装 12 块硬盘, 这需要 6 个机柜(42U计算).


有同学会说了, 那我让用户直接来一个长密码, 16位! 这需要 2.25 × 10^31 byte! 总没问题了吧? 你觉得用户会记得住一个长达16位的密码吗? 他肯定会用手机号/生日随便再来点什么对吧. 那对应的彩虹表也会相当的小. (用户密码熵不可置信问题)


那么有了salt就可以了吗? 不可以, salt也要足够长/足够复杂. 这样才能达到增加 hash target 的信息量(也就是熵)的目的. 这样才会让彩虹表的制作足够难.


设想一个极端场景, 数据库被"拖库"了, 不但hash结果, 甚至salt都已经是已知的了, 源代码也被泄露了, 散列方法无论是 bcrypt 还是 Argon2 还是 Scrypt 人家都知道了, 甚至你的库进行着定期的rehash, 人家连过去的版本也搞到了(可能进行特征/侧信道攻击), 我们该如何保护用户的密码原文?


那就只有salt的熵了(期望用户密码拥有足够的熵不靠谱). 而提升salt的长度可以有效提升存储熵的空间. 这就是 @Ivony 回答论述的主要内容.


所以正确的做法是, 要求用户的密码有足够的熵(复杂度检测, 不通过让他换密码). 以及salt也要有足够的熵. 然后请用相应语言的密码学库里面的散列方法. 或者干脆, 用脑子记住用bcrypt.


试想一下 cracker 去 StackOverflow 问: "各位大佬, 求一个1024bit长度的彩虹表", 会不会被人笑爆然后问, 怎么? 你捡到外星U盘还是外星电脑了? :)




大师 Bruce Schneier 有句话, 被称作 Schneier's Law:


"Anyone, from the most clueless amateur to the best cryptographer, can create an algorithm that he himself can’t break."


人家大师就是大师, 不会直接折了你面子, 但其实意思就是, 别自己发明加密算法.


- 真正安全的算法是久经社区考验的, bcrypt已经22年了(1999-2021), Scrypt也12年了(2009-2021).

- 而且是要社区流行的. 光自己看的懂没意义, 别人也能用才有意义, 才能成为标准.


Schneier 对此又说了:


"There are two kinds of cryptography in this world: cryptography that will stop your kid sister from reading your files, and cryptography that will stop major governments from reading your files."


(世界上有两种密码学: 一种是阻止你妹妹阅读你的文件的密码学, 另一种是阻止强大的政府阅读你文件的密码学.)




最后.


建议多读书, 书上写的很清楚:


"If the salt is big enough, it essentially makes dictionary attacks infeasible."


Secure Programming Cookbook for C and C++


延伸阅读, 现在已经不太建议用PBKDF2了(因为有FPGA/ASIC), 应该转向其他的 GPU/内存/ASIC 抗性更强的散列方法:


medium.com/analytics-vi


user avatar   Ivony 网友的相关建议: 
      

没有意义,早就有md5+sha1的彩虹表了。


至于说加盐对抗彩虹表的人,也绝大多数不明白这里面的原理和逻辑。

加盐的确是对抗彩虹表,但是到底是怎么对抗的,其实很多人仍然是一知半解。要搞清楚这一点,就要搞清楚彩虹表的原理。

彩虹表很简单,就是预先计算出所有可能密码的哈希值,然后破解的时候查表好了。

彩虹表的方式理论上无法防御(这与加密算法不同),只要是有限长度的密码,就可以被彩虹表攻击。并且彩虹表可以复用,所以计算单次密码攻防成本也是扯淡,随着时间的推移,彩虹表只会增长不会收缩


所以对抗彩虹表只有一个方法,这也是绝大多数人压根儿没有弄明白的事情,彩虹表最大的敌人是密码的可能性,更进一步的如果考虑到彩虹表的无限增长的问题,所以彩虹表的唯一防御手段是增加密码长度!

所以加盐的本质目的是:增加密码长度


密码长度的增加,破解该密码的彩虹表的大小需要呈指数增长,这才是防御彩虹表的根本原因。


所以加盐是必须的,但是你加的盐太短了,把你的盐当作密码的一部分去查表就完了……



其实说白了吧,如果你只是要防御彩虹表,仅仅针对彩虹表防御,你只需要把你的密码拉到特别长,彩虹表直接失效,有没有盐都失效了……

更进一步的,如果你的密码长度足够长,长到比哈希值的长度还要多出不少。这时候即便别人找到了一个碰撞,那大概率也不是你的密码了,你密码的安全可以得到更彻底的保护……


最后再补充一点好了,彩虹表破解的是你的密码,他的依据是大部分人在不同的网站会使用同一个密码,所以得到你的密码,就能入侵别的网站。对于已经侵入后台拿到你密码哈希值的黑客来说,再去伪造你的身份已经没啥意义了,因为他既然都已经侵入了网站的后台,在这个网站想干点儿啥还需要你那密码么?


user avatar   flily 网友的相关建议: 
      

看来你不知道什么是salt。生成一个随机数,我们称之为salt,然后在数据库中记录salt和h=hash(pwd + salt),查询的时候,得到用户的口令p,然后从数据库中查出salt,计算hash(p+salt),看是不是等于h,等于就是对的,不等于就是不对的。

单纯使用MD5之所以不好,并不是说MD5这种方法容易遭到破解,而事实上对于MD5求原象或者第二原象,也就是“逆计算”这种破解,没有什么很好的方法。只能通过预先计算知道许多MD5的对应关系,存在数据库中,然后使用的时候反查,例如我知道'password'的MD5值是5f4dcc3b5aa765d61d8327deb882cf99,那么我就用一个数据库存起来,只要我看到5f4dcc3b5aa765d61d8327deb882cf99,我就知道这个是口令'password‘使用MD5处理之后的值,原来的口令就是'password'。MD5在身份鉴别系统中用于口令保护已经是很久了事情了,大部分黑客也有针对这种Hash方式准备相应的数据库进行反查,这种数据库称为彩虹表。

所以,为了对抗彩虹表,我们要做的工作是避免预先计算,让攻击者无法(或者非常困难)提前计算好彩虹表。

为了反映为何彩虹表计算是可行的,我们再来算一下。我们假设用户可能输入的口令是键盘上的小写字母和数字,共26+10=36种,之所以这样假设是因为 一个用户比较多的系统中总是会有一些弱口令用户的,我们假设输入的口令至少5个字符,至多12个字符,那么用户可能的输入一共有:

,而12个字节可能的组合应有

种。如果再考虑到用户为了方便记忆,输入的口令是一些已经存在的单词或是词组,可能的输入将会远远少于。用户可能的输入少了,就给了我们枚举的空间。

为了阻止这种枚举,加salt的方法是扩大用户输入的一种简单有效的途径,随机生成一个16字节的随机数,加上用户本身输入的至多12个字符的口令,可能的输入就有种,这么多种可能性,任何一个机构和组织都没有办法存储规模如此庞大的彩虹表。

另外一种方法是通过提升Hash的复杂度,延长攻击者进行暴力破解时所消耗的时间。现在显卡用于并行计算实在太容易,6位纯数字的口令在显卡看来就是秒破。Hash算法的多次迭代就是最简单的延长计算时间的方法,Apache的htpasswd就使用了MD5的1000次迭代,不过只是使得这些口令稍微难破解一些。

另外,题中使用了SHA1和MD5两种算法的方法,除了稍微提升一点计算的难度以外,并没有多好,这种组合方法不能增加用户输入的可能性,另外虽然SHA1生成的是160位的Hash,但是由于输入是一个128位的MD5,所以输出也至多只可能有种可能,猜测的范围也没有缩小。所以这是原来回答我建议你使用更多次数(如1000次)MD5迭代的原因,至少应当有一个方面有稍微大一些的加强。

另外

此文(暴力密码破解器 ocl-Hashcat-plus 支持每秒猜测最多 80 亿个密码,意味着什么?

)中有数据可以供参考,bcrypt是一种有效对抗口令Hash破解的算法,建议使用。




  

相关话题

  “Facebook 开发的高性能PHP虚拟机 HHVM 比官方的 PHP解释器 快超过9倍”的说法是否属实? 
  有哪些破解密码或加密的经历? 
  关于互联网安全,你有什么看法? 
  如何看待百度于2017年2月28日晚疑似停止服务? 
  各个编程语言都有哪些「黑点」? 
  解除加密的PDF文件密码有什么办法? 
  目前来说在网站架构方面采用nobackend这种方案构建是否真的可行? 
  HTTPS体系中若攻击者将自己公钥上传CA得到签名,并将两者一起用于篡改证书的中间人攻击会怎样? 
  为什么现在大部分密保都是靠手机号确认身份,运营商的SIM卡系统很难被入侵吗? 
  怎样防范被人肉搜索? 

前一个讨论
知名媒体人、《南方周末》创始人左方去世,他的一生有哪些值得铭记的贡献?
下一个讨论
为什么在 HTTP 协议中,使用的是 Windows 换行方式而不是 UNIX 换行方式?





© 2025-05-31 - tinynew.org. All Rights Reserved.
© 2025-05-31 - tinynew.org. 保留所有权利