综合了几篇文章的内容,以C#的计算结果为参考标准,总结出CFB模式的流程(OFB模式先占坑,未来再填)
CFB模式
密文反馈(CFB,Cipher feedback)模式与ECB和CBC模式只能够加密块数据不同,可以将块密码变为自同步的流密码;CFB的解密过程几乎就是颠倒的CBC的加密过程。
注意:CFB、OFB和CTR模式中解密也都是用的加密器而非解密器。
CFB的加密工作分为两部分:
1.将一前段加密得到的密文再加密;
2.将第1步加密得到的数据与当前段的明文异或。
由于加密流程和解密流程中被块加密器加密的数据是前一段密文,因此即使明文数据的长度不是加密块大小的整数倍也是不需要填充的,这保证了数据长度在加密前后是相同的。
CFB模式克服了ECB/CBC模式需要等待8个字节才能加解密的缺点,它采用了分组密码作为流密码的密钥流生成器;
特点:
每次加密不大于64位;
加密算法和解密算法相同,不能适用于公钥算法;
使用相同的密钥和初始向量的时候,相同明文使用CFB模式加密输出相同的密文;
可以使用不同的初始化变量使相同的明文产生不同的密文,防止字典攻击;
加密强度依赖于密钥长度;
加密块长度过小时,会增加循环的数量,导致开销增加;
加密块长度应为8位的整数倍(即字节为单位);
一旦某位数据出错,会影响目前和其后8个块的数据
我的总结
ECB/CBC模式对数据进行8字节分块,而OFB模式可以更小分块来计算,这个分块大小在C#的DESCryptoServiceProvider
类中称为FeedbackSize
,以bit位为单位,经测试C#中该值只能为8bit,也就是只能逐字节计算,但我认为理论上可以分16bit、24bit字节等来计算,只要该值不超过IV向量的大小(也就是64bit)就行。
加密示例(FeedbackSize=8)
明文:11 22 33 44 55 66 77 88
密钥:12 34 56 78 90 11 22 33
初始IV:AA BB CC DD 77 88 99 55
第一步:用密钥对初始IV进行ECB模式加密得到X=B9 EF 8C 84 E2 B5 FF 53
第二步:用X的第1字节B9 与 明文的第1字节11 进行异或 得到密文的第1字节A8
第三步:将初始IV左移8位,最右边填充密文的第1字节A8,得到新的IV=BB CC DD 77 88 99 55 A8
第四步:用密钥对新的IV进行ECB模式加密得到X=34 91 48 8F BA A2 FC 18
第五步:用X的第1字节34 与 明文的第2字节22 进行异或 得到密文的第2字节16
第六步:将IV左移8位,最右边填充密文的第2字节16,得到新的IV=CC DD 77 88 99 55 A8 16,用密钥对新的IV进行ECB模式加密得到X=99 42 70 47 50 9A B8 DC,用X的第1字节99 与 明文的第3字节33 进行异或 得到密文的第3字节AA
…..
第N步:依此类推,最终得到8字节密文A8 16 AA 7B 36 B3 5F D6
解密示例(FeedbackSize=8)
密文:A8 16 AA 7B 36 B3 5F D6
密钥:12 34 56 78 90 11 22 33
初始IV:AA BB CC DD 77 88 99 55
第一步:用密钥对初始IV进行ECB模式加密得到X=B9 EF 8C 84 E2 B5 FF 53
第二步:用X的第1字节B9 与 密文的第1字节A8 进行异或 得到明文的第1字节11
第三步:将初始IV左移8位,最右边填充密文的第1字节A8,得到新的IV=BB CC DD 77 88 99 55 A8
第四步:用密钥对新的IV进行ECB模式加密得到X=34 91 48 8F BA A2 FC 18
第五步:用X的第1字节34 与 密文的第2字节16 进行异或 得到明文的第2字节22
第六步:将IV左移8位,最右边填充密文的第2字节16,得到新的IV=CC DD 77 88 99 55 A8 16,用密钥对新的IV进行ECB模式加密得到X=99 42 70 47 50 9A B8 DC,用X的第1字节99 与 密文的第3字节AA 进行异或 得到明文的第3字节33
…..
第N步:依此类推,最终得到8字节明文11 22 33 44 55 66 77 88
OFB模式
OFB模式(输出反馈:Output feedback),OFB是先用块加密器生成密钥流(Keystream),然后再将密钥流与明文流异或得到密文流,解密是先用块加密器生成密钥流,再将密钥流与密文流异或得到明文,由于异或操作的对称性所以加密和解密的流程是完全一样的。
OFB与CFB一样都非常适合对流数据的加密,OFB由于加密和解密都依赖与前一段数据,所以加密和解密都不能并行。
特点:
与CFB类似,以下都是不同之处;
因为密文没有参与链操作,所以使得OFB模式更容易受到攻击;
不会进行错误传播,某位密文发生错误,只会影响该位对应的明文,而不会影响别的位;
不是自同步的,如果加密和解密两个操作失去同步,那么系统需要重新初始化;
每次重新同步时,应使用不同的初始向量。可以避免产生相同的比特流,避免”已知明文”攻击 ;