如何安全存储密码都不知道,难怪我会被面试官吊打咯!( 三 )


明文输入:1233445TGNVFsha1密文:fc58f924f193654f6388cac13b6061e99c7dbabcsha224密文:97cdfc11422a8311e812809711b3159c4530f5f183841f7fe111fd92sha384密文:2de74b23f770126eb51ec328f591c2290fd3bed8756d0e4dffa32af9296006444c334288bd820b1297d8087977131f0fsha512密文:96be48daec3779f6d83b991a4f281280884578b2b68a2cf5c481838e48c199c8795f89328a85f208d791465bad28acac440be3a1397eafb0bfefd60d6b9f8a9bGPU在进行密码破解领域有绝对的把控力,对于md5和sha1这些算法运算速度非常之快达到每秒x亿次,如果再串联多组GPU进行破译那么速度将更快 。
但是就目前而言sha224/256/385/512算法还是安全的,在2017年谷歌宣布其对sha1撞库的最新研究,基于此呼吁全球相关机构公司进行算法升级,如图展示了谷歌使用两份不同的文件得到相同sha1的例子:

如何安全存储密码都不知道,难怪我会被面试官吊打咯!

文章插图
 
尽管获得了撞库进展,但是谷歌付出的成本也是巨大的:攻击算法分为两个阶段,其中第一个阶段如果使用单CPU需要6500年,第二阶段使用单GPU需要110年,可谓成本之高 。
所以我们如果采用单向无盐哈希存储密码时要避免使用MD5/sha-1这些被大量研究过的短摘要,可以使用sha-256这种更安全的摘要算法,比特币目前就有使用sha-256作为其相关算法 。
4.3.3 算法升级的思考更换更安全的摘要加密算法确实是有一定效果的,但是算力的进步是我们无法预测的,正如md5和sha-1刚被应用时也是当前的算力无法逾越的,但是随着并行计算和量子计算的发展,诸如sha-256/512这些现在看来更安全的算法什么时候会被证明又不安全也不得而知 。
但是如果我偏偏想把单车开出摩托的感觉咋办?怎样用md5这种弱摘要算法能不能实现一个强密码存储系统呢?
 
面对这个朴实的诉求,我们接着聊 。
5.彩虹表攻击攻击是为了更好的防守,相克相生 。
5.1 暴力破解暴力破解一般可以分为 计算暴力破解和查表暴力破解,如图:
如何安全存储密码都不知道,难怪我会被面试官吊打咯!

文章插图
 
在说彩虹表Rainbow Table之前先说一下字典穷举,这个比较好理解:比如某家网站的密码构成是长度为12位含字母、数字、特殊符号,这样我们就可以根据这个特征生成一个所有密码的全排列集合,然后再进行比如md5摘要计算得到一个哈希值,然后把这个映射关系存储下来 。
使用字典法暴力破解时就如同一个巨大的hash表可以迅速降低时间,但是随着加密算法的升级和密码复杂度的提升,字典就会变得非常非常大,理论上无法存储使用 。
 
人们通过努力找了一种时间和空间折中的方案-彩虹表,它将单独时间或者单独空间的不可接受变为可接受,可以说是个非常有用的东西,第一次听这个名字时诧异于为什么叫彩虹表 。
5.2 空间存储效率问题在探究彩虹表之前,我们先思考这样一个问题:如何用最少的存储空间表达最多的信息量呢?
  • C语言中的例子想一下在C语言中我们在传结构体或者数组时一般只传递首地址,其他的元素可以根据这个首地址和偏移量来实现访问,所以我们用一个地址就可以遍历所有的变量,存储效率很高 。
  • 二叉树的例子二叉树的链式存储和顺序存储都可以借助于根节点,依据左右孩子节点的关系从而实现全树的检索和遍历,这样我们在对外传输二叉树时只需要给出根节点即可,不必全部给定 。
  • 西游记的例子西游记主角是师徒5人,算了白龙马的...,我们可以存储这5个人的信息,但是觉得有点浪费啊,因为我们知道他们5个之间是有关系的,存储一个就能找到另外四个了 。
如图展示了全量存储5人信息的场景:
如何安全存储密码都不知道,难怪我会被面试官吊打咯!

文章插图
 
如图展示了利用师徒之间的关系部分存储:
如何安全存储密码都不知道,难怪我会被面试官吊打咯!

文章插图
 
简单说明下:只存储唐僧,唐僧为入口根据其大徒弟关系得到了孙悟空,从孙悟空依据师弟关系得到另外三人,这个很像数据库的索引了...
画外音:有时候很多元素内部是存在联系的,我们不必全量展示和存储这些信息,这样会造成空间上的浪费,如果我们借助于这些内在联系就可以用少量数据作为入口获取到所有的数据,这是一种思想吧!
理解这个存储效率问题对于认识彩虹表有很大的帮助 。
试想字典穷举是把建立所有明文和密文之间的映射,这样就等价于唐僧师徒5人每个人都存储,但是如果我们找到了某些明文之间的内在联系,那么我是否可以只存储少量明文就可以表达这些具备内在联系的明文和密文的映射关系呢?


推荐阅读