攻击方法
攻击方法主要分为猜和查
猜,指穷举法和字典攻击,去猜用户的密码
查,指构建键值对 \((key,\ value)\),根据 \(value\) 去查 \(key\)
\(1.\) 字典攻击
事先制作好密码表,逐一去试,是单纯穷举法的改进
\(2.\) 明文-哈希索引表
建立大量 \((key,\ value)\) 的键值对,查询时直接对着 \(value\) 逆向查询 \(key\)
设哈希密文空间为 \(\rho\),密文长度为 \(n\),那么这样的存储空间复杂度为 \(O(|\rho| n)\),查询时间是 \(O(1)\)
虽然查询时间快,但是存储的空间消耗巨大
\(3.\) 预计算哈希链
\(3.1\ R\) 函数与哈希链
构造 \(R\) 函数,满足定义域和值域与哈希函数 \(H\) 相反
考虑简化问题,设密码明文为 \(6\) 位十进制数,\(H\) 将其映射为 \(8\) 位十六进制数,那么 \(R\) 将哈希过的值映射回 \(6\) 位十进制数
规定常数 \(k\),我们选取大量随机明文进行 \(k\) 次 \(H,\ R\) 映射,最终保留链表的首尾 \((h,\ t)\),便可以得到一个哈希链集,上述例子 \(k = 2\)
一条哈希链包含了多个 \((key,\ value)\) 对,但是我们只存储了首尾 \((h,\ t)\),这在存储空间上的进步非常明显
\(3.2\) 查询
考虑查询,对密文 \(C\) 不断做 \(R, H\) 映射(至多 \(k\) 次),若得到的结果 \(C'\) 是哈希链集的某条链的尾巴,那么对于这个哈希链,从头往下进行 \(H,\ R\) 映射,直到找到明文 \(P\)
如果做了 \(k\) 次 \(R,\ H\) 映射都没有找到链尾,那么意味着查询失败
对于上述例子,考虑密文 \(EEAF1C41\),做一次 \(R\) 运算后得到 \(742834\),属于哈希链集的某一条链的尾巴,于是从头 \(123456\) 进行运算,最终找到明文为 \(342111\)
\(3.3\) 复杂度
空间复杂度为 \(O(\frac{|\rho|n}{k})\),时间复杂度为 \(O(k)\)
\(3.4\) 哈希链的困境——碰撞
考虑如下两条哈希链
从 \(\textbf{123456}\) 处发生了碰撞,哈希链剩下所有部分全部碰撞,这样一来,存储的键值对 \((key,\ value)\) 远远低于预期
\(4.\) 哈希链的改进——彩虹表
\(4.1\) 彩虹表做的改进——\(R\) 函数集
彩虹表在哈希链的基础上,采用 \(k\) 个 \(R\) 函数,分别记为 \(R_{1},\ R_{2},\ ..,\ R_{k}\)
这可以保证,两条链碰撞后继续碰撞的概率减小,从而提高了键值对存储的效率
\(4.2\) 彩虹表的查询
给定密文 \(C\),假设做 \(j\) 次 \((R_{i},\ H)\) 映射找到存储的尾巴
declare ciphertext C, plaintext P
for (j = 1; j <= k; ++j)
for (i = k - j + 1; i <= k; ++i)
P = Ri(C), C = H(P)
if (P is in RainbowTable)
get the plaintext
空间复杂度仍然是 \(O(\frac{|\rho|n}{k})\),时间复杂度为 \(O(k^2)\)
\(4.3\) 防御彩虹表攻击
在计算 \(H\) 时加入随机 \(salt\),本质上随机化了哈希函数 \(H\),但是彩虹表只对确定的 \(H\) 奏效