9.3 密码分组链接模式
链接将一种反馈机制加进分组密码中:前一个分组的加密结果被反馈到当前分组的加密中,换句话说,每一分组被用来修改下一分组的加密。每个密文分组不仅依赖于产生它的明文分组,而且依赖于所有前面的明文分组。
在密码分组链接(CBC)模式中,明文被加密之前要与前面的密文进行异或运算。图9.3(a)展示了分组链接是如何工作的,第一个分组明文被加密后,其结果也被存在反馈寄存器中,在下一明文分组加密之前,它将与反馈寄存器进行异或作为下一次加密的输入,其结果又被存进反馈寄存器,再与下一分组明文进行异或,如此这般直到消息结束。每一分组的加密都依赖于所有前面的分组。
图9.3 密码分组链接模式
解密一样简单易行(见图9.3b)。第一个分组密文被正常的解密,并将该密文存入反馈寄存器,在下一分组被解密后,将它与寄存器中的结果进行异或。接着下一个分组的密文被存入反馈寄存器,如此下去直到整个消息结束。
用数学语言表示为:
C i= E k (PiÅ C i-1)
P i = Ci-1Å DK( C i)
初始向量
CBC模式仅在前面的明文分组不同时才能将完全相同的明文分组加密成不同的密文分组,因此两个相同的消息仍将加密成相同的密文。更糟糕的是,任意两则消息在它们的第一个不同之处出现前,将被加密成同样的结果。
一些消息有相同的开头:如,一封信的信头,“发件人”行,或其它东西。虽然使用分组重放是不可能的,但这些相同的开头的确给密码分析者提供了一些有用的线索。
防止这种情况发生的办法是用加密随机数据作为第一个分组,这个随机数据分组被称之为“初始化向量(IV),“初始化变量”,或“初始连接值”。IV没有任何意义,它只是使每个消息唯一化。当接收者进行解密时,只是用它来填充反馈寄存器,然后将忽略它。时间邮戳是一个好的IV,当然也可以用一些随机比特串作为IV。
使用IV后,完全相同的消息可以被加密成不同的密文消息。这样,偷听者企图再用分组重放进行攻击是完全不可能的,并且制造密码本将更加困难。尽管要求用同一个密钥加密的消息所使用的IV是唯一的,但这也不是绝对的。
IV不需要保密,它可以明文形式与密文一起传送。如果觉得这样错了,那就看一下如下讨论:假设我们有一个消息的各个分组,B1、B2、….B i ,B1用IV加密,B2使用B1的密文作为IV进行加密,B3用B2的密文作为IV进行加密,如此类推。所以,如果有n个分组,即使第一个IV是保密的,那仍然有N—1个“IV”暴露在外。因此没有理由对IV进行保密;它只是一个虚拟密文分组——你可以将它看作链接开始的B0分组。
填充
就象ECB模式一样进行填充,但在许多应用中需要使密文与明文有同样的长度。或许明文被加密后就放在内存原来的位置,这样,你必须对最后那一个短分组进行不同的加密处理。假定最后一分组有j比特,在对最后一个完整分组加密之后,再将其加密,然后选择密文的最左边j比特让其跟不完整分组(短分组)进行异或运算。如图9.4所示。
图9.4 CBC模式最后短分组的加密方法
这种方法的不足之处是当Mallory不能恢复最后明文分组时,他可以通过修改密文的一些个别比特系统地改变它们。如果最后n比特密文含有重要信息,这将是一个弱点,如果最后几位只含一些简单的不重要的东西,就无关紧要。
密文挪用是一个很好的方法(参见图9.5)[402]。Pn—1是最后一个完整的明文分组,Pn是最后的短明文分组。Cn—1是最后一个完整的密文分组,C n是最后短的密文分组。C‘是一个中间结果并非传送密文的一部分。该方法的好处是明文消息的所有位都通过了加密算法。
图9.5 CBC模式下的密文挪用
错误扩散
CBC具有在加密端是密文反馈和解密端是密文前馈的性质,这意味着要对错误进行处理。明文分组中单独一位发生错误将影响密文分组以及其后的所有密文分组。这没什么大不了,因为解密将反转这种影响,恢复的明文也还是那个错误。
密文错误更加常见。信道噪音或存储介质损坏很容易引起这些错误。在CBC模式中,密文中一个单独比特的错误将影响一个分组以及恢复明文的1比特错误。含有1比特错误的分组是完全不能恢复,随后的分组在同样的位置有1比特的错误。
密文的小错误能够转变成明文很大的错误,这种现象叫做错误扩散。它是最烦人的事。错误分组的第二分组之后的分组不受错误影响,所以CBC模式是“自已恢复的”。虽然两个分组受到一个错误的影响,但系统可以恢复并且对所有后面的分组都不受影响。CBC是用于自同步方式的分组密码算法的一个实例,但仅在分组级。
尽管CBC很快能将比特错误恢复,但它却不能恢复同步错误。如果从密文流中增加或丢失1比特,那么所有后续分组要移动1比特,并且解密将全部是错误的。任何使用CBC的加密系统都必须确保分组结构的完整,要么用“帧”,要么在有多个分组大小的内存分组中存储。
安全问题
一些潜在的安全问题是由CBC的结构引起的。首先,因为密码分组都是用同样的方式影响后面的分组,所以Mallory可以在加密消息的后面加上一些分组而不被发觉。当然,它或许被解密成一堆杂乱的数据,但在很多情况下这是不需要的。
如果你正在使用CBC,你应当组织好明文使你能知道消息在何处结束,并且能检测出额外附加的分组。
其次,Mallory可以通过改变一个密文分组,控制其余解密的明文分组。例如,如果Mallory切换一个密文位,那么就使得整个密文分组不能被正确解密,但紧接的分组在相应的同一位置出现1比特错误。在很多情况下这是所需要的。整个明文消息应当包括某些控制冗余或鉴别。
最后,尽管通过链接把明文的模式被隐藏起来了,但很长的消息仍然有其模式。由生日悖论可以预知2m/2个分组后就有完全相同的分组,其中m为分组的大小。对一个64-比特的分组,也就是约34G字节。在消息必须足够长时,才有这样的问题。