赞
踩
密码算法可以分为分组密码和流密码两种。
分组密码(block cipher)是每次只能处理特定长度的一块数据的一类密码算法,这里的“一块”就称为分组(block)。此外,一个分组的比特数就称为分组长度(block length)。
例如,DES 和三重 DES 的分组长度都是64比特。这些密码算法一次只能加密 64 比特的明文,并生成64比特的密文。AES 的分组长度可以从128 比特、192比特和256比特中进行选择。当选择 128 比特的分组长度时,AES一次可加密 128 比特的明文,并生成 128 比特的密文。
流密码(streamcipher)是对数据流进行连续处理的一类密码算法。流密码中一般以1比特、8比特或32比特等为单位进行加密和解密。
分组密码处理完一个分组就结束了,因此不需要通过内部状态来记录加密的进度;相对地,流密码是对一串数据流进行连续处理,因此需要保持内部状态。
分组密码算法只能加密周定长度的分组,但是我们需要加密的明文长度可能会超过分组密码的分组长度,这时就需要对分组密码算法进行迭代,以便将一段很长的明文全部加密。而迭代的方法就称为分组密码的模式(mode)。说人话就是对分组密码加密的方式。在学习之前,我觉得大部分都会认为:如果明文很长的话,将明文分割成若干个分组再逐个加密不就好了吗?因为我自己就是这么认为的QAQ。事实上可没有那么简单。将明文分割成多个分组并逐个加密的方法称为 ECB模式,这种模式具有很大的弱点(后续介绍)。如果在编写加密软件使用 ECB 模式,会在不经意间产生安全漏洞,所以千万不能使用 ECB模式。
模式有很多种类,分组密码的主要模式有以下5种:
ECB模式:Electronic CodeBook mode(电子密码本模式)
CBC模式:Cipher Block Chaining mode(密码分组链接模式)
CFB模式:Cipher FeedBack mode(密文反馈模式)
OFB模式:Output FeedBack mode(输出反馈模式)
CTR模式:CounTeR mode(计数器模式)
在了解各个模式之前,先来熟悉一下待会要接触的两个概念。
明文分组是指分组密码算法中作为加密对象的明文。明文分组的长度与分组密码算法的分组长度是相等的。
密文分组是指使用分组密码算法将明文分组加密之后所生成的密文。
图示为:
将明文分组直接加密的方式就是ECB模式,这种模式是最简单的,也是最逊的,弱点很多,所以根本不用。
ECB模式的全称是Electronic CodeBook 模式。在ECB模式中,将明文分组加密之后的结果将直接成为密文分组。
图示为(这边解密箭头有点问题,应该是密文->解密->明文,凑活看):
使用 ECB 模式加密时,相同的明文分组会被转换为相同的密文分组。可以将其理解为是一个巨大的“明文分组->密文分组”的对应表,因此 ECB 模式也称为电子密码本模式。当最后一个明文分组的内容小于分组长度时,需要用一些特定的数据进行填充 (padding )。
ECB 模式是所有模式中最简单的一种。ECB 模式中,明文分组与密文分组是一一对应的关系,因此,如果明文中存在多个相同的明文分组,则这此明文分组最终都将被转换为相同的密文分组。这样一来,只要观察一下密文,就可以知道明文中存在怎样的重复组合,并可以以此为线索来破译密码,因此 ECB 模式是存在一定风险的。
ECB 模式中,每个明文分组都各自独立地进行加密和解密,但这其实是一个很大的弱点。假如存在主动攻击者,他能够改变密文分组的顺序。当接收者对密文进行解密时,由于密文分组的顺序被改变了,因此相应的明文分组的顺序也会被改变。也就是说,攻击者无需破译密码就能够操纵明文。在这个场景中,攻击者不需要破译密码,也不需要知道分组密码算法,他只要知道哪个分组记录了什么样的数据(即电文的格式)就可以了。
看个简单的例子。假设分组长度为 128 比特(16字节),某银行的转账请求数据由以下了个分组构成:
分组1=付款人的银行账号
分组2=收款人的银行账号
分组了=转账金额
银行在收到转账请求数据后,就会将数据中指定的金额从付款人的账户转移到收款人的账户中。现假设一个“从 A-5374 账户向 B-6671账户转账1亿元”的转账请求数据,用16进制数据表示如下:
明文分组1= 41 2D 35 33 37 34 20 20 20 20 20 20 20 20 20 20(付款人:A-5374)
明文分组2= 42 2D 36 35 37 31 20 20 20 20 20 20 20 20 20 20(收款人:B-6671)
明文分组3= 31 30 30 30 30 30 30 30 30 20 20 20 20 20 20 20(转账金额:100000000)
下面我们将上述数据用 ECB 模式进行加密,从加密后的数据是看不出明文分组的内容的。
密文分组1= 59 7D DE CC EF EC BA 9B BF 83 99 CF 60 D2 59 B9(付款人:? ? ? ?)
密文分组2= DF 49 2A 1C 14 8E 18 B6 53 1F 38 BD 5A A9 D7 D7(收款人:? ? ? ?)
密文分组3= CD AF D5 9E 39 FE FD 5D 64 8B CC CB 52 56 8D 79(转账金额:? ? ? ?)
接下来,攻击者将密文分组1和2的内容进行对调:
密文分组1= DF 49 2A 1C 14 8E 18 B6 53 1F 38 BD 5A A9 D7 D7(收款人:? ? ? ?)
密文分组2= 59 7D DE CC EF EC BA 9B BF 83 99 CF 60 D2 59 B9(付款人:? ? ? ?)
密文分组3= CD AF D5 9E 39 FE FD 5D 64 8B CC CB 52 56 8D 79(转账金额:? ? ? ?)
攻击者只是对调了密文分组1和2的顺序,并没有试图破译密码。而银行对上述信息解密后,就会变成下面这样:
明文分组1= 42 2D 36 35 37 31 20 20 20 20 20 20 20 20 20 20(付款人:B-6671)
明文分组2= 41 2D 35 33 37 34 20 20 20 20 20 20 20 20 20 20(收款人:A-5374)
明文分组3= 31 30 30 30 30 30 30 30 30 20 20 20 20 20 20 20(转账金额:100000000)
原本请求的内容是从 A-5374 账户向 B-6671 账户转账1亿元,现在却变成了从 B-5671 账户向 A-5374 账户转账1亿元,完全相反!通过这个例子可以看出,BCB模式的一大弱点就是可以在不破译密文的情况下操纵明文。在ECB 模式中,只要对任意密文分组进行替换,相应的明文分组也会被替换。此外,攻击者所能做的还不仅限于替换,例如,如果将密文分组删除,则相应的明文分组也会被删除;如果对密文分组进行复制,则相应的明文分组也会被复制。
CBC模式是将前一个密文分组与当前明文分组的内容混合起来进行加密的,这样就可以避免ECB模式的弱点。
CBC模式的全称是Cipher Block Chaining模式,因为它的密文分组像链条一样相互连接在一起,所以就叫这名儿。
在CBC模式中,首先将明文分组与前一个密文分组进行XOR运算(异或),然后再进行加密。
图示为(这边解密箭头有点问题,应该是密文->解密->XOR->明文,凑活看):
如果将一个分组的加密过程分离出来,就可以容易比较出ECB模式和CBC模式的区别。ECB模式只进行了加密,而CBC模式则在加密之前进行了一次XOR。
图示为:
当加密第一个明文分组时,由于不存在”前一个密文分组“,所以需要事先准备一个长度为一个分组的二进制序列来代替,这个序列称为初始化向量(initialization vector),通常缩写为 IV。一般来说,每次加密时都会随机产生一个不同的二进制序列来作为初始化向量。
明文分组在加密之前一定会与”前一个密文分组“进行XOR运算,因此即便明文分组1和2的值是相等的,密文分组1和2的值也不一定是相等的。这样一来,ECB模式的缺陷在 CBC模式中就不存在了。
详细看一看 CBC 模式的加密过程。在CBC模式中,我们无法单独对一个中间的明文分组进行加密。例如,如果要生成密文分组 3,则至少需要凑齐明文分组 1、2、3才行。再来看看CBC模式的解密过程。现在假设CBC 模式加密的密文分组中有一个分组损坏了(例如由于硬盘故障导致密文分组的值发生了改变等)。在这种情况下,只要密文分组的长度没有发生变化,则解密时最多只会有2个分组受到数据损坏的影响。
图示为:
假设CBC 模式的密文分组中有一些比特缺失了(例如由于通信错误导致没有收到某些比特等等),那么此时即便只缺失了1比特,也会导致密文分组的长度发生变化,此后的分组发生错位,这样一来,缺失比特的位置之后的密文分组也就全部无法解密了。
图示为:
假设主动攻击者的目的是通过修改密文来操纵解密后的明文。如果攻击者能够对初始化向量中的任意比特进行反转(即将1变为0,将0变为1),则明文分组(解密后得到的明文分组)中相应的比特也会被反转。这是因为在CBC 模式的解密过程中,第一个明文分组会和初始化向量进行XOR运算。
图示为:
这样,攻击者就可以对初始化向量进行攻击,但是想要对密文分组也进行同样的攻击就非常困难。例如,攻击者将密文分组1中的某个比特进行了反转,则明文分组2中相应的比特也会被反转,然而这1比特的变化却会对解密后的密文分组1中的多个比特造成影响。说人话就是,攻击者只想让明文分组1产生所期望的特定变化是很蓝的啦。
CFB模式的全称是Cipher FeedBack模式。在CFB模式中,前一个密文分组会被送回到密码算法的输入端。所谓反馈(feedback),这里指的就是返回输入端的意思。
图示为(这边箭头没错了捏):
在ECB模式和CBC模式中,明文分组都是通过密码算法进行加密的。然而,在CFB模式中,明文分组并没有通过密码算法来直接进行加密。从图示可以看出明文分组和密文分组之间并没有经过“加密”这一步骤。在CFB 模式中,明文分组和密文分组之间只有一个XOR。
将 CBC 模式与 CFB 模式对比一下,就可以看出其中的差异了。在CBC模式中,明文分组和密文分组之间有XOR和密码算法两个步骤,而在CFB 模式中,明文分组和密文分组之间则只有 XOR。
图示为:
在生成第一个密文分组时,由于不存在前一个输出的数据,因此需要使用初始化向量(IV)来代替,这一点和CBC模式是相同的。一般来说,我们需要在每次加密时生成一个不同的随机二进制序列用作初始化向量。
CFB 模式是通过将“明文分组”与“密码算法的输出“进行XOR运算来生成“密文分组”的。在CFB模式中,密码算法的输出相当于一次性密码本中的随机二进制序列。由于密码算法的输出是通过计算得到的,并不是真正的随机数,因此 CFB模式不可能像一次性密码本那样具备理论上不可破译的性质。
CFB 模式中由密码算法所生成的二进制序列称为密钥流(key stream)。在CFB模式中,密码算法就相当于用来生成密钥流的伪随机数生成器,而初始化向量就相当于伪随机数生成器的“种子”。在CFB模式中,明文数据可以被逐比特加密,因此我们可以将CFB模式看做是一种使用分组密码来实现流密码的方式。
CFB 模式的解密过程见前图。CFB模式解密时,需要注意的是分组密码算法依然执行加密操作,因为密钥流是通过加密操作来生成的。
对 CFB 模式可以实施重放攻击 (replay attack)。
举个不恰当的例子。有一天,lbw向tx发送了一条消息,这条消息由4个密文分组组成。主动攻击者将该消息中的后了个密文分组保存了下来。转天,lbw又向tx发送了内容不同的4个密文分组(假设lbw使用了相同的密钥)。攻击者用昨天保存下来的3个密文分组将今天发送的后3个密文分组进行了替换。于是,当tx解密时,4个分组中就只有第1个可以解密成正确的明文分组,第2个会出错,而第3个和第4个则变成了被攻击者替换的内容(也就是昨天发送的明文内容)。这边解释一下:明文分组2出错是因为密文分组1是正确的,经过加密形成的密钥流也是正确的,但是密文分组2是错误的,所以明文分组2出错;而明文分组3和4是以前的明文分组是因为密文分组2和3都是昨天的内容,所以加密之后进行XOR运算得到的是以前的明文分组。可以看到,攻击者没有破解密码,就成功地将以前的电文混入了新电文中。而第2个分组出错到底是通信错误呢,还是被人攻击所造成的呢?tx是无法做出判断的。
图示为:
OFB模式的全称是Output FeedBack模式。在OFB模式中,密码算法的输入会反馈到密码算法的输入中。
OFB模式并不是通过密码算法对明文直接进行加密的,而是通过将“明文分组”和“密码算法的输出”进行XOR来产生“密文分组”的,在这一点上OFB模式和CFB模式非常相似。
图示为:
和CBC、CBF一样,OFB模式也需要使用初始化向量。一般来说,我们需要在每次加密时生成一个不同的随机二进制序列用作初始化向量。
OFB模式和CFB模式的区别仅仅在于密码算法的输入。
CFB模式中,密码算法的输入是前一个密文分组,也就是将密文分组反馈到密码算法中,因此就有了“密文反馈模式”这个名儿。
相对的,OFB模式中,密码算法的输入则是密码算法的前一个输出,也就是将输出反馈回密码算法,因此就有了“输出反馈模式”这个名儿。
图示为:
由于CFB模式中是对密文分组进行反馈的,因此必须从第一个明文分组开始按顺序进行加密,也就是说无法跳过明文分组1而先对明文分组2进行加密。相对地,在OFB模式中,XOR所需要的比特序列(密钥流)可以事先通过密码算法生成,和明文分组无关。只要提前准备好所需的密钥流,则在实际从明文生成密文的过程中,就完全不需要动用密码算法了,只要将明文与密钥流进行XOR就可以了。这就意味着只要提前准备好密钥流就可以快速完成加密。换个角度来看,生成密钥流的操作和进行XOR运算的操作是可以并行的。
CTR 模式的全称是CounTeR 模式。CTR 模式是一种通过将逐次累加的计数器进行加密来生成密钥流的流密码。
CTR 模式中,每个分组对应一个逐次累加的计数器,并通过对计数器进行加密来生成密钥流。也就是说,最终的密文分组是通过将计数器加密得到的比特序列,与明文分组进行XOR而得到的。
图示为:
每次加密时都会生成一个不同的值(nonce)来作为计数器的初始值。当分组长度为128比特(16字节)时,计数器的初始值可能是类似于下面这种形式:
66 1F 98 CD 37 A3 8B 4B 00 00 00 00 00 00 00 01
------------nonce------------- |---------分组序号------------
其中前8个字节为nonce,这个值在每次加密时必须都是不同的。后8个字节为分组序号,这个部分是会逐次累加的。在加密过程中,计数器的值会产生如下变化:
66 1F 98 CD 37 A3 8B 4B 00 00 00 00 00 00 00 01 明文分组1的计数器(初始值)
66 1F 98 CD 37 A3 8B 4B 00 00 00 00 00 00 00 02 明文分组2的计数器
66 1F 98 CD 37 A3 8B 4B 00 00 00 00 00 00 00 03 明文分组3的计数器
66 1F 98 CD 37 A3 8B 4B 00 00 00 00 00 00 00 04 明文分组4的计数器
… …
按照上述生成方法,可以保证计数器的值每次都不同。由于计数器的值每次都不同,因此每个分组中将计数器进行加密所得到的密钥流也是不同的。也就是说,这种方法是用分组密码来模拟生成随机的比特序列。
CTR模式和OFB模式一样,都属于流密码。OFB模式是将加密的输出反馈到输入,而CTR模式则是将计数器的值用作输入。
图示为:
CTR模式的加密和解密使用了完全相同的结构,这个特点和OFB模式一样。
此外,CTR模式中可以以任意顺序对分组进行加密和解密,因此在加密和解密时需要用到的“计数器”的值可以由nonce和分组序号直接计算出来。这一性质是OFB模式所不具备的。能够以任意顺序处理分组,就意味着能够实现并行计算。在支持并行计算的系统中,CTR
模式的速度是非常快的。
错误与机密性方面,CTR 模式也具备和OFB模式差不多的性质。假设CTR模式的密文分组中有一个比特被反转了,则解密后明文分组中仅有与之对应的比特会被反转,这一错误不会放大。
换言之,在CTR 模式中,主动攻击者可以通过反转密文分组中的某些比特,引起解密后明文中的相应比特也发生反转。这一弱点和OFB模式是相同的。不过CTR模式具备一个比OF 模式要好的性质。在OFB模式中,如果对密钥流的一个分组进行加密后其结果碰巧和加密前是相同的,那么这一分组之后的密钥流就会变成同一值的不断反复。在CTR模式中就不存在这一问题。
模式 | 优点 | 缺点 | 备注 |
---|---|---|---|
ECB模式 | ● 简单 ● 快速 ● 支持并行计算(加密、解密) | ● 明文中的重复排列会反应在密文中 ● 通过删除、替换密文分组可对明文进行操控 ● 对包含某些比特错误的密文进行解密时,对应的分组会出错 ● 不能低于重放攻击 | 不应使用 |
CBC模式 | ● 明文中的重复排列不会反应在密文中 ● 能够解密任意密文分组 ● 支持并行计算(仅解密) | ● 对包含某些比特错误的密文进行解密时,第一个分组的全部比特以及后一组的相应比特会出错 ● 加密不支持并行运算 | 推荐使用 |
CFB模式 | ● 不需要填充 ● 能够解密任意密文分组 ● 支持并行计算(仅解密) | ● 加密不支持并行运算 ● 对包含某些比特错误的密文进行解密时,第一个分组的全部比特以及后一组的相应比特会出错 ● 不能低于重放攻击 | 推荐用CTR模式代替 |
OFB模式 | ● 不需要填充 ● 可事先进行加密、解密的准备 ● 加密解密使用相同的结构 ● 对包含某些错误比特的密文进行解密时,只有明文中相应的比特才会出错 | ● 不支持并行运算 ● 主动攻击者反转密文分组中的某些比特时,明文分组中相应的比特也会被反转 | 推荐用CTR模式代替 |
CTR模式 | ● 不需要填充 ● 可事先进行加密、解密的准备 ● 加密解密使用相同的结构 ● 对包含某些错误比特的密文进行解密时,只有明文中相应的比特才会出错 ● 支持并行计算(加密、解密) | 主动攻击者反转密文分组中的某些比特时,明文分组中相应的比特也会被反转 | 推荐使用 |
文章内容已同步更新至 lbw的小窝,欢迎大家参观,批评指正。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。