【密码学】彩虹表

        以前和很多人一样,对彩虹表的理解是片面的:以为彩虹表是一个大的“明文->密文”的映射表。按照这个理解(也就是暴力破解)某个哈希函数的彩虹表的容量是超大超大的,即使对明文做了分类。
        今天看了一下上面链接的那个帖子后,对彩虹表有了更确切的理解。彩虹表( Rainbow table )所谓的time-memory trade-off,并不是简单地“以空间换时间”,而是双向的“交易”,在二者之间达到平衡。
        首先我们简单回忆下哈希函数的特性,一个输入对应一个固定输出,可能存在碰撞(多个输入对应的哈希值相同),不可逆。

一、哈希链集

1.哈希链的原理

        在彩虹表之前,已经出现了对哈希函数的破解算法,被称为“预计算的哈希链集”(Precomputed hash chains)。当面对要破解的哈希函数H,首先要定义一个函数R,该函数的定义域和值域与哈希函数相反,通过该函数可以将哈希值映射为一个与原文相同格式的值。需要强调的是,由于哈希函数是不可逆的,所以对于密文进行R运算几乎不可能得到明文原文。

(1)构造一条哈希链

此处k=2

        H,R重复次数记为k,k值应该适当,k太大容易出现重复子链,太小存储空间太大。我们只存储每条链的起点和终点,若干条哈希链构成哈希链集。

(2)使用哈希链破解密文

已知一个密文,假设是y:

(i)对密文进行R运算R(y),将R(y)在终点表中查询;

        若查询失败,继续进行H、R运算,查询;最多进行K次R运算,要么查询成功,要么破解失败。

        若查询成功,执行步骤(ii)

(ii)查明文并验证

        由查询匹配到的终点对应的起点,重复进行H、R运算:起点→my=H(m)→R(y)

        起点→my是查明文过程,y→R(y)是验证过程。查到明文就是m。

(3)举例

            y=D2A82C9A,R(y)=vfkkd,查表失败;H(vfkkd)=0CAFC376,R(0CAFC376)=crepa,查表成功。

            相应起点终点分别是zhihu、crepa 。

            查明文并验证:

            


        一条哈希链代表了k组明文密文对,但它只存储起点终点,因此相对于暴力表大大节省了空间。哈希链破解最耗时的操作就是查询终点,由于终点数(链数)远远小于密文数,因此相对于暴力表大大节省了时间。

2.R函数

R函数的选取要求:

(1)将值域限定在固定的范围之内。事实上,在计算和下载彩虹表时,需要使用不同的库的。按照不同的哈希函数、字符集、密码长 等分为很多个不同的库。

(2)尽量保证R的值域均匀分布,以减少碰撞。

然而实际上很难找到能满足这些要求的完美的R函数。当计算中发生碰撞时,就会出现如下的子链重复的问题:


图中加粗的部分,所涉及到的明文是完全重复的,因此这两条哈希链能解密的明文数量就远小于理论上的明文数2k。不幸的是, 由于集合只保存链条的首末节点,因此这样的重复链条并不能被迅速地发现。随着碰撞的增加,这样的重复链条会逐渐造成严重的冗余和浪费。

二、彩虹表

1.彩虹表的构造

        为了解决前面“子链重复”的问题,不再使用单一的R函数,而是使用不同的Ri函数(故称为彩虹表)。

此处k=3

        当两链发生碰撞的位置不在同一位置时,后续的R函数的不一致使得链条的后续部分也不同,从而最大程度地减小了链条中的重复子链。同时,如果在极端情况下,两个链条有1/k的概率在同一序列位置上发生碰撞,导致后续链条完全一致,这样的链条也会因为末节点相同而检测出来,可以丢弃其中一条而不浪费存储空间。

不同的彩虹表使用的R函数集不同。

2.使用彩虹表破解密文

彩虹表的使用比哈希链集稍微复杂一些。  

已知一个密文,假设是y:

(i)假设密文在k-1位置,对密文进行Rk运算Rk(y),将Rk(y)在终点表中查询;若查询成功,执行步骤(ii),若查询失败,

        假设密文在k-2位置,对密文进行Rk-1、H,Rk运算,将结果Rk(H(Rk-1(y)))在终点表中查询;若查询成功,执行步骤(ii),若查询失败,

            假设密文在k-3位置,......

            假设密文在0位置,对密文进行反复Ri,H运算,将结果在终点表中查询;若查询成功,执行步骤(ii),若查询失败,破解失败。

(ii)查明文并验证

        由查询匹配到的终点对应的起点,重复进行H、R运算:起点→my=H(m)→Ri(y)

        起点→m→y是查明文过程,y→Ri(y)是验证过程。查到明文就是m。


举例:

y=85E4969A

假设密文在2位置:R3(y)查询失败;假设密文在1位置:R3(H(R2(y)))查询失败;

假设密文在0位置:R3(H(R2(H(R1(y)))))=biqkz查询成功;

查明文并验证:明文就是share

3.时空分析

        彩虹表减少了没必要的重复子链,相对于哈希链集节省了空间;假设链长位2k+1(密文k个,明文K+1个),在最坏的情况下即破解失败的情况下,哈希链集进行K次R运算,彩虹表进行1+2+3...+K=k(K+1)/2次R运算,所以彩虹表比哈希链集耗时更多。这就是时空的平衡。

三、防御彩虹表攻击

        关于彩虹表的防御方法,与哈希函数H有关。

1.加盐

        最常用的方法,就是加盐(salt),实际上相当于改变了哈希函数H的形式。由于彩虹表在构造和破解的过程中,反复用到了H,H如果发生了改变,则已有的彩虹表数据就完全无法使用,必须针对特定的H重新生成彩虹表,这样就提高了破解的难度。

2.增加哈希函数H的复杂度

        防御彩虹表的另一种方法是提高H函数的复杂度,例如将H定义为计算一千次MD5后的结果。由于H在算法中的重复性,当单次H函数的计算耗时增加,意味着彩虹表的生成时间会大大的增加,从而也能提高破解的成本。

转自:知乎Smallay

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值