为什么不能计算两次哈希以及在什么情况下不能计算两次哈希?算法原理解析,如何利用函数预测博彩走势

2026-01-14

  哈希算法,SHA256,哈希函数,加密哈希,哈希预测/哈希算法是博彩游戏公平性的核心,本文详细解析 SHA256 哈希函数的运作原理,并提供如何通过哈希技术进行博彩预测的方法!

为什么不能计算两次哈希以及在什么情况下不能计算两次哈希?哈希算法原理解析,如何利用哈希函数预测博彩走势

  假如一个系统允许最大16位密码,密码允许大小写字符、数字以及标点等符号——我懒得算了,假设有100种取值吧。那么,这个系统可能的密码数(密钥空间)就是100^16级别。

  攻击者可以换一个思路:用户设置密码,自己肯定得记住;想记住,那么太过诡异的字符组合就不太可能,并且用户的密码往往也不会太长(除非专业用户,很少有人会如此自虐)。

  所以,他可以列出所有单词、缩写,再组合不同单词甚至加上大小写变化;然后再搭配不同符号作为单词之间的分割——这个空间仍然很大,但比起100^16,那就小太多了。现代计算机(集群)跑上个把月或更长时间,差不多就能穷举出来了。

  不仅如此,他还可以弄到流传在黑市上的、之前泄露的明文密码:那么,普通用户可能想到的密码,应该就很难超脱这个范围了。

  这叫“字典攻击”;比起暴力穷举,效率已经可以接受了。尤其是攻击可下载到本地的内容时,“跑字典”早已是基础课了。

  但,远程攻击时,只要服务器加一个 重试间隔 和/或 重试次数 限制,字典攻击就失效了。

  攻击者可以再想深一步:相对于数学原理上的无解,网络服务器的防御总是有机可乘的。他可以想办法攻击服务器,拿到服务器上存储的密钥啊——服务器肯定要存密钥相关信息的,不然用户怎么登录?

  不过,稍微会玩的,在服务器上存储的都是已经hash过的密码;理论上是不可从hash结果反推出密码的。

  hash函数的值域极大,理论上不可能在有效时间内穷举整个hash值域,从而反推出原始密码。

  但是,攻击者可以拿出自己的密码字典,用同样的算法计算字典里的密码的hash值——现代计算机速度够快、存储容量也够大,完全可以做到“把字典里的密码的hash值全部计算出来、存储到类数据库结构里”。

  不仅如此,他还可以利用“彩虹表”暴力覆盖几乎全部短密钥空间,使得只要你的密码位数和用到的符号种类(大小写字符、数字、标点符号等)不够多,就逃不过他的手心(什么是彩虹表? - 网络安全 - 知乎;随便感谢某匿名用户提醒,避免了我误导他人)。

  一旦这个工作完成(视字典大小/要覆盖的密钥长度,大概需要几小时到几个月吧),那么只要用户密码落入覆盖范围,利用黑客从服务器上偷来的hash值一反查,就可以知道密码明文了。

  事实上,攻击者可以边计算边搜索,并且优先计算那些“大众密码”——很可能从服务器拿到加密密钥后几分钟,那些用简单的“大众密码”的用户就完蛋了。也许不到三天,一半以上的用户已经被扒的干干净净了。

  不管你如何取hash函数——不管是n次hash还是先hash再反序再用加密,或者再加几道工序也一样——攻击者都可以用同样的算法处理他的密码字典、以及生成对应的彩虹表,从而直接由hash值找出对应的密码。

  因为,“加盐”相当于强行在用户密码前后附加若干随机字符——注意每个用户加的“盐”应该各不相同,不然攻击者只要把这个固定的“盐”字符串附加进去行了,和n次hash没两样,并不能给黑客带来更多麻烦。

  反之,如果每个用户加的“盐”各不相同,那么攻击者将不得不对每个用户跑字典/生成彩虹表——假设你有一万用户,那么他的彩虹表就将膨胀一万倍:前面提到过,做这种准备需要的时间,经常是以天甚至月为单位的,一万天就是三十多年,一万月……

  哪怕攻击者只试“大众密码”,“必须为每个用户跑字典”的限制也可以尽量拖延时间,把损失降到最低。

  换句话说,给所有人加同样的盐、给所有人用同样一个多次hash(或其它手段)的摘要算法,效果是一样的:攻击者只需要针对这个算法跑一遍字典或者生成一次彩虹表,你的所有用户就被扒的干干净净了。

  而每个人加不同的盐,就相当于为每个人“定制”了一个摘要算法;攻击者攻破用户A时跑出的数据,到了用户B那里就完全作废了。你有一百万个用户,他就得完成一百万次独立攻击,而这是完全不可能的。

  所谓加解密,玩的就是时间上的不平等。如果加密时的一份时间,换不来解密时间的倍数甚至指数增长,那么这个时间付出在密码学上就是毫无意义的。

  可见,加盐显著增加了攻击者的时间/空间成本,使得彩虹表攻击不再合算;配合安全审计等工作,就足以保护用户数据安全了(当然,用简单密码的小白用户……还是自求多福吧)。

  这里有两个问题,第一个是两次哈希事实上是另一种哈希算法,当然加盐也是另一种哈希算法,但是加盐的算法有很多种,别人不一定有彩虹表,但是两次哈希的只有一种,很可能别人手上就有。

  另一个问题就是两次哈希导致值域变小,因为哈希函数的值域大小总是会小于等于定义域,所以多次哈希后,就有可能造成值域缩小。当然,用于密码哈希的时候,这个问题并不那么重要(相较于彩虹表攻击)。

  一切都是为了提高攻击者破解密码的成本。关键是你的数据是否有价值让人花费资源进行破解。破解成本从低到高依次为:常用hash算法--两次hash--加固定盐--加随机盐

  众所周知,出于安全考虑,现在的数据库不直接存储明文密码,而是存储密码hash后的摘要。用户输入密码后,后台将输入hash后再和数据库比对。这样的好处是即使攻击者拖来了数据库,也无法得知密码。他必须找到一个值,使其经过同样的hash算法后得到的摘要与密码相同。这个值可能就是密码,也可能与密码不同。hash的过程是不可逆并伴随信息损失的,不同的值hash后可能会有相同的结果,我们称之为碰撞。

  对于常用的hash算法,比如md5,我们可以很方便地找到一种叫彩虹表的东西。你可以把彩虹表看作一个特殊的,超大的数据库。只要花费少量时间,绝大部分的md5摘要都能被反查出对应的原文。

  所以我们现在说对密码直接md5是不安全的。因为脱裤后,利用彩虹表直接反查就能得到与密码hash后摘要相同的字符串。同理,因为两次hash的做法也比较常见,虽然不像md5一样烂大街,对密码进行两次常用的hash运算也已经有现成的彩虹表。

  再来看看加固定盐的情况,如果你所做的只是在用户密码后面加上一个“1”然后md5,效果。。。聊胜于无吧。这样的盐与其说是防范手段倒不如说是心理安慰。彩虹表基本可以覆盖较短(视表的大小而定,其实也不能算短)空间内的所有字符组合。而在这样的空间内,原文发生碰撞的概率微乎其微。举个例子,密码是10个字符以内的ascii码字符,用户的密码是dj1Hsk,加盐后变成dj1Hsk1,md5后为d1151dfb723be8b0999568ee11e850b5。反查彩虹表后,照样可以把dj1Hsk1揪出来,再减去1,密码也就到手了。轻松愉快~固定盐几乎没有起到任何作用。

  那盐应该怎么加呢?保险的方法是加到原本的信息量大于hash后摘要的信息量为止。举个丧心病狂点的例子——我把整本《哈姆雷特》作为盐加到密码后面。这样如果还能有人通过hash摘要反推出我们的原文——密码+哈姆雷特,那他一定是可以不受热力学第二定律制约的完美生物了。

  固定盐一般是指盐的选取仅和密码有关——比如说我存储的是 hash(密码+hash(密码)+固定字符串)。这样可以避免别人使用现成的彩虹表。小网站其实做到这种程度也足够安全了(当然还有更推荐的方法比如加随机盐)。其实这种做法相当于“定制”了一个自己的hash函数。这个hash函数是全站通用的。但是如果数据足够值钱,不排除有人从零开始,或是穷举,或是字典攻击,总之造出一个巨大的hash-原文表来,然后把数据一锅端了。

  然后就是比较推荐的做法——加随机盐。随机盐的取值加入了和密码无关的因素,比如用户名。这样相当于每个用户的hash函数都不相同,避免了被一张表一锅端的情况,大大增加了破解成本。做到这种地步,基本上可以认为足够安全了

  另:彩虹表只是一种特殊的节省存储空间的手段。彩虹表覆盖到的每一条值都是老老实实一个一个计算出来的,相比直接hash还多了还原的步骤。造一个彩虹表比直接从零开始穷举更费事。更何况反函数的取用更是一个技术活儿。所以我们看到的彩虹表都是md5,sha1等常用算法的。一台电脑几个月时间就想做一个彩虹表简直天方夜谭。攻击者拿到数据库也根本不会去做个彩虹表来造福大众。分割线下的是彩虹表的简介。

  简单说来,彩虹表的思路就是对hash后的摘要进行“分类”后再进行破解。把散列值比做锁的话,它就像一个满是抽屉的大柜子。先找到锁的钥匙在哪个抽屉里,在从抽屉里拿出钥匙按顺序来试。说它是“空间换时间”,空间的占用就是抽屉的数目,抽屉越多,每个抽屉里面的钥匙可能就越少,破解需要的时间也就随之减少。

  那么如何知道钥匙在哪个抽屉里呢?彩虹表用了一个非常巧妙的办法。我们已经有了一个hash函数,记作H函数,现在我们来构造一个R函数,这个函数能将H函数生成的值逆向变化为和原文相同格式的值。

  举个例子,构造H(x)=x^2 mod 37 ;R(x)=2*x+3 (这两个函数的构造问题很大,只是举个栗子而已,轻拍)。然后我们任取一个数作为起始值(比如59),交替进行H和R变换:

  于是我们就得到了这样一条长长的链条,称为彩虹链,每一个链节的后半部分是前半部分H变换的结果。提取链条头尾的59和21,好,这就是一个抽屉! 彩虹表不存储整条链,只存储链条的头尾,大大节省了空间。

  那么这样的链条怎么用呢?比如说我知道了密码hash后的值是11,那么我交替进行R变换和H变换,得到这样的链条:

  这时我对照彩虹表,发现21是一条链的尾部。于是我取出头部的59开始变换:

  你看,彩虹表的链条只存储了头尾两个信息,你却可以推出整条链来。要想把每个值的md5记录下来,计算机的硬盘容量是远远不够的。但如果只是记录链条头尾,硬盘表示我可以一战!这也是为什么彩虹表一般只有几百G却能破解绝大多数密码的原因。

地址:广东省广州市天河区88号 客服热线:400-123-4567 传真:+86-123-4567 QQ:1234567890

Copyright © 2012-2025 哈希游戏推荐 版权所有 非商用版本