实验背景:
哈希函数H:X→Y ,其中,X为定义域,Y为值域,且|X|>|Y|,能够实现任意长度的输入转换成固定长度的输出。
密码学哈希函数H应满足如下的要求:
(1) 压缩:x任意长,H(x)固定长;
(2) 容易从x计算出 H(x);
(3) 抗原像攻击:已知y ∈ Y,要找出x∈X,使得H(x) = y是困难的;
(4) 抗第二原像攻击:已知x ∈ X, 找出另一个x' ∈ X,使得H(x')=H(x)是困难的;
(5) 抗碰撞性:找出任意两个不同的x, x' ∈ X,使得H(x) = H(x')是困难的。
利用哈希函数的上述性质,可以构造一个谜题问题:已知哈希函数H,一个值v以及目标范围T,寻找x,使得H( v|| x) ∈T。
求解上述问题等价于需要找到一个输入值,使得输出值落在目标范围T内,例如,如果哈希函数H的输出为n比特,那么输出值可以是任何一个0~2n-1范围内的值,可以定义T为0~2k (k < n) 范围内的值。目标范围T的大小决定了解这个谜题的求解难度。如果T包含所有n比特长的串,即k=n, 那么求解等价于计算一次哈希值;如果T只包含一个元素,即k=1,则这个求解是最难的,相当于给定一个哈希值,找出其中的一个原像。一般的,k越小,求解花费的时间越长。
求解上述哈希函数构造的谜题问题形成了工作量证明,可以用于对付垃圾邮件发送者、拒绝服务攻击以及设计密码货币的共识算法。
本实验即设计并求解基于哈希函数构造的谜题问题。
符号约定及要求
HASH(m):表示对消息串进行哈希计算;
n:哈希函数值的长度,要求至少为160比特;
d:以16进制位表示的前缀0的个数;
SHR(h, k):对无符号数h右移k位;
v||x:两个字符串首尾相连
实验步骤:
一构造谜题并求解
1、 d = 1
2、 v = 你的学号或姓名
3、 从x=1出发,增加x的值并转化为对应的串x,直到 HASH(v||x)< SHR(2n-1, d*4)
4、记下这时的x的值
5、 取d=2,3,重复2~4
思路分析:
第1和第5步可以用循环来解决:for(d=1;d<4;d++){}
第2步:取v=”陈华展”;
第3步也可以利用for循环解决:for(x=1; HASH(v||x)>=SHR(2n-1, d*4);x++);
这里主要目的是求出x的值使得HASH(v||x)< SHR(2n-1, d*4)成立;
第4步:打印出第3步求得的x值
代码实现:
利用php脚本实现这个简单的程序:
其中哈希计算采用的是sha1函数加密,n取值160,对无符号数2n-1右移d*4位可看作2n-1除以2的d*4次方;于是可取shr= SHR(2n-1, d*4)= 2n-1/2d*4;
程序运行脚本如下:
运行结果:
程序深入改进:
- 记录程序运行过程所花费的时间
运行结果:程序运行了6毫秒
2.增加d循环的次数为6
运行结果:记录的x值疯狂递增,程序运行了22408毫秒(约22.5秒)
二从哈希函数的数学性质的角度分析实验结果
由哈希函数的定义可知:当哈希函数的输出长度n确定时,哈希函数的值域Y也固定了,对于任意的信息m,其哈希值H(m) ∈Y,而对于Y的子集T,H(m) ∈T不一定成立,由于哈希函数的计算不可逆,所以H(m)是否落入T中是随机的,而且当T越小时,H(m) ∈T成立的概率就越小,即要找到m使得H(m) ∈T就越困难。当T只包含一个元素时,要找到m使得H(m) ∈T相当求解哈希函数的原像。
在本次实验中,随着d的增加,要找到x使得 HASH(v||x)< SHR(2n-1, d*4)变得越困难,程序的计算量就不断增大,求得的x值有很大概率会一直增加,所花费的时间也会相应地上升。
实验思考:
为什么基于哈希函数的谜题问题可以用于设计对付垃圾邮件的发送和拒绝服务攻击的系统?你会如何利用这类工作量证明的方法设计上述的系统?
答:在上述哈希函数构造的谜题问题中可以发现,当d的值很小时,并不会给计算机造成太大的计算负担,而随着d的增加,计算机的计算负担不断上升,工作量大幅度上升甚至影响系统的正常运行。基于以上原理,可以这样设计一个对付垃圾邮件的发送和拒绝服务攻击的系统:
当一台计算机要发送某些消息(例如邮件、SYN请求等)时,消息系统要求发送方计算出一个满足一定范围的哈希值,并且规定:
(1) 在计算完成之前不允许发送方发送消息;
(2) 在一定的周期内,发送方首次要求发送消息,系统要求哈希值范围会相对较大,不会造成太大的计算负担;
(3) 在一定的周期内,如果发送方再次要求发送请求,则哈希值的范围随着发送次数的增加而不断减小,大大增加发送方的计算负担,从而阻止一个发送方在短时间内发送大量信息;
在这个系统中,不会正常发送消息的计算机造成困扰,而对于那些发送垃圾邮件或者其他有害信息则会有极大的阻拦效果。