被加密的原文需要分成组,每组长度与密钥长度相同,再分别加密。实际上,对称加密里还有一种类型算法叫做流加密。所谓流加密,就是使用一个与原文同样长度的密钥,与原文数据按位进行异或操作,得到的结果就是密文。解密过程和加密类似,就是用同样的密钥,对密文在进行按位异或,得到明文。这和异或运算的原理有关,假设P是原文,K是密钥,E是密文,⊕代表异或运算,则有如下加密算式:
E=P⊕K
根据异或运算原理,相同的数异或结果为0,任何数与0异或得到的是它本身,故可推导如下解密算式:
E⊕K=P⊕K⊕K
=P⊕0
=P
可以这么理解,流加密就是给原文数据的每一位依次戴个帽子,把原数据隐藏起来,解密就是摘掉帽子,把原数据露出来。因此它的优点就是简单快捷。看到这里估计你也意识到了,既然加解密方法这么简单,那么流加密的重点应该就在密钥上吧?事实确实如此,比如,我们以A、B为明文,使用同样的密钥K,进行流加密得到加密结果E(A)和E(B),则根据异或运算特点可以做出如下算式:
E(A)⊕E(B)⊕B=(A⊕K)⊕(B⊕K)⊕B
=A⊕B⊕(K⊕K)⊕B
=A⊕B⊕0⊕B
=A⊕B⊕B
=A⊕0
=A
可以看出,只要拿到两个密文和一个明文,就可以计算出另一个明文。实际中,密文是比较容易拿到的,而攻击者也完全可以自己提交一个明文送给系统加密。即在密钥相同的情况下,明文是很容易被计算出来的。因此流加密的安全性来源于其密钥的安全性。实际上,信息论的祖师爷香农早在1948年就在理论上证明了如果流加密的密钥要不小于与被加密原文长度,每加密的密钥做到一次一密。这样的加密就实现了“完善保密性”,也就是“绝对安全”。当然,目前这种“绝对安全”只能无限趋同,不可能真正做到。
流加密的密钥可分为同步流密码和自同步流密码。同步流密码是指密钥流的生成过程是独立的,明文及密文不参与其中;而自同步流密码(也叫异步流密码)中的密文参与到密钥流的生成。
同步流密码一般采用伪随机数生成算法生成随机数列作为密钥组成部分。显然,密钥的随机性越强,明文中的统计特征被覆盖得更好,加密的强度也就越高。在现实中经常使用的一种方法是用线性反馈移位寄存器(LFSR)来生成伪随机序列。线性反馈移位寄存器是一种电路,它是许多密钥流生成器的基本部件;非常适合硬件的实现;可以产生大周期序列;可以产生具有良好统计性质的序列;易于利用代数方法对其进行分析。
除了线性反馈移位寄存器外,还有一种基于较短的一串给定密钥,派生出无限长(实际上达到原文长度即可)的伪随机密码流的流加密方法。具有代表性的是就RC4(Rivest Cipher 4)算法。RC4采用一个256字节的状态向量S,256字节的暂时向量T,和用户自定义的密钥输入构成。通过自定义的密钥生成暂时向量之后,状态向量S与暂时向量T通过一系列的置换算法产生可用于加密的伪随机密钥流,参与加密。
流加密最重要的就是密钥,但容易出问题的也是密钥。
首先流加密属于对称加密,那就有一个密钥交换的问题,也就是加解密双方事先得有一个办法可以安全地交换密钥。但流加密的密钥长度是和明文一样长的,而且只能使用一次,交换的成本相对加密行为来说不低。而且,既然能安全交换密钥,为什么不直接安全交换同样长度的明文呢?
其次,流加密安全性来源于密钥的随机性,也就是伪随机序列的随机性。但前面随机数一文说过,并不存在真随机数。像RC4算法、WEP协议、DVD使用的数据加密协议,由于设计或其他限制,也都存在密钥随机序列在一定条件下重复出现的概率。这些都会影响流加密的安全效果。
总体来讲,由于本身密钥的使用成本及安全性问题,流加密在实际应用中出现的频率远低于分组加密。但流加密的一些优点,也被分组加密算法所吸收应用,如通过不同的工作模式实现类似流密码算法的特性。