在流密码中,密钥不是完全随机的,而是一种伪随机密钥。
伪随机数发生器(PRG):是一个本身没有随机性的完全确定的函数 G ,取一个种子为输入(种子具有随机性),用 {0,1}^s 表示所有长度为 s 的字符串,{0,1}^s 叫做种子空间,将 s 位种子映射到一个长得多的字符串 {0,1}ⁿ ,G:{0,1}^s→{0,1}ⁿ,n>>s。种子可能只有128位,但能扩展成一个长得多的字符串。
以种子为私钥 k ,使用发生器将种子扩张成长得多看起来随机的伪随机序列 G(k) ,将伪随机序列和明文异或,得到密文。c = E(K,m) = m⊕G(k);m = D(K,c) = c⊕G(k)。
流密码是安全的,安全性依赖于使用的发生器,但其密钥比明文短得多,不是完美安全的。
不可预测性:对于各个位置,即对所有 i ,没有有效的破解算法 A ,以不可忽略的概率预测出第 i+1 位。
安全的发生器必须具有不可预测性,即不能由前面的部分预测出后面的部分。如:拿到密文,而明文的前半部分已知,可以异或出伪随机序列的前半部分,如果伪随机序列可预测,就可以预测出完整的伪随机序列,从而密文完全破解,还原整个明文。
线性同余法:将当前伪随机数的数值乘以 A 再加上 C ,然后将除以 M 得到的余数作为下一个随机数,A 和 C 是整数,M 是质数,迭代执行 $R_0$ = (A × 种子 + C) mod M,输出后一位。线性同余法不具备不可预测性,不能用于密码技术。
对一次性密码本的攻击
两次密码本攻击:如果同样的密码本为不同的明文加密,就不再安全。
$C_1$ ← $m_1$⊕PRG(k)
$C_2$ ← $m_2$⊕PRG(k)
攻击者截获 $C_1$ 和 $C_2$ 可以得出 $m_1$⊕$m_2$ ,由于英语有足够的冗余,如果给定两明文的异或,是可以还原出两个明文的。因此,流密钥不能被重复使用。
利用可修改性攻击:一次性密码本和流密钥不提供完整性保护。攻击者截获密文 m⊕k ,将密文和一特定值 p (子置换密钥)异或得到 (m⊕k⊕p)⊕k ,解密后得到 m⊕p ,成功对明文造成特定影响,而对密文的修改不会被检测出来。
几种流密码
RC4(面向软件):种子大小可变,被用作流密码的密钥。将 128 位密钥扩展成 2048 位,执行一个简单的循环,每轮输出一个字节。
Google在 HTTPS 中使用RC4。
RC4已被伪随机数发生器取代。
RC4弱点:
- 第二个字节等于 0 的概率为 2/256 ,而不是 1/256 ,加密时,第二个字节可能不会被加密。此外,第一个和第三个字节也是不均匀的。
- 观察一段很长的输出,出现序列 00 的可能性更大。
- 密钥关联攻击。
CSS(面向硬件):已被完全破解,用于加密DVD电影。CSS是基于线性反馈移位寄存器(LFSR)的。
CSS密钥是 5 个字节,40 位。(seed = 5 bytes = 40 bits)
CSS使用 2 个LFSR,一个 17 位(1联结上前2个字节),一个 25 位(1联结上后3个字节)。
eStream:
PRG:{0,1}^s × R →{0,1}ⁿ,n>>s,{0,1}^s 为seed,R 为新鲜值(只要密钥定下来,永不重复的值)。
E(k, m; r) = m⊕PRG(k; r)。(k; r) 这个有序对永不重复,不被多次使用,底线是可以重复使用密钥,新鲜值确保了有序对唯一。
一个生成器是安全的,不仅特定的统计测试认为它的输出是随机的,事实上,对于所有有效(测试算法总在有限步内终止并返回结果)的统计测试,都认为输出是随机的。
完美安全:
对于任意等长的消息m,只要这个m属于消息空间(就是说用这个加密算法可以加密m),那么用加密密钥k加密后,加密结果“看起来都一样”,没法看出来这是从m,还是从其他什么消息加密得来的。
语义安全:
计算机在多项式复杂度内看加密结果,觉得“看起来都一样”。
安全的PRG是语义安全的。