一、DES加密算法简介
DES(Data Encryption Standard)是目前最为流行的加密算法之一。DES是对称的,也就是说它使用同一个密钥来加密和解密数据。
DES还是一种分组加密算法,该算法每次处理固定长度的数据段,称之为分组。DES分组的大小是64位,如果加密的数据长度不是64位的倍数,可以按照某种具体的规则来填充位。
从本质上来说,DES的安全性依赖于虚假表象,从密码学的术语来讲就是依赖于“混乱和扩散”的原则。混乱的目的是为隐藏任何明文同密文、或者密钥之间的关系,而扩散的目的是使明文中的有效位和密钥一起组成尽可能多的密文。两者结合到一起就使得安全性变得相对较高。
DES算法具体通过对明文进行一系列的排列和替换操作来将其加密。过程的关键就是从给定的初始密钥中得到16个子密钥的函数。要加密一组明文,每个子密钥按照顺序(1-16)以一系列的位操作施加于数据上,每个子密钥一次,一共重复16次。每一次迭代称之为一轮。要对密文进行解密可以采用同样的步骤,只是子密钥是按照逆向的顺序(16-1)对密文进行处理。
二、DES加密算法加密原理
DES是采用分组加密。使用64位的分组长度和56位的密钥长度,将64位的输入经过一系列变换得到64位的输出。DES算法利用多次组合替代算法和换位算法,通过混淆和扩散的相互作用,把明文编辑成密码强度很高的密文。解密则使用了相同的步骤和相同的密钥。
64位数据为一组进行加密;
初始置换根据一张8*8的置换表,将64位的明文打乱
与56位的密钥经16轮次迭代运算形成的初始密文
最后经过初始逆置换得到分组的最终密文
三、DES加密算法的实现
考虑到DES算法中涉及的位操作很多,因此DES算法通常都是在硬件中实现。DES算法中的图表和术语(通过线、框画的流程图,以及诸如S盒、P盒这样的术语)使其更倾向于在硬件中实现,当然,软件实现也有它的价值所在。在软件开发中,通过几种基本的指令操作来帮助实现DES中的各种置换、转换以及替换操作都是很有效的。
des_encipher
函数des_encipher将明文的一个64位的明文分组通过DES算法加密。
由于DES的一个很好的特点是同样的过程既能用来加密数据也能用来解密数据,因此des_encipher只需要简单的调用des_main,而des_decipher同样也只需要调用des_main即可。
函数des_main通过使用其参数direction来确定到参数source提供的数据是明文还是密文。direction参数只是简单地修改子密钥的顺序。
在des_encipher中,direction设置为encipher。
函数des_main()首先检测参数key是否为NULL。这将允许des_encipher的调用者重用上一次调用时计算出来的子密钥。将子密钥数组subkeys声明为static类型。如果key不为NULL,将计算子密钥。
要计算子密钥,可以按照前面介绍过的步骤(计算16个子密钥)来执行。key的转换是通过函数permute来实现的,这里就是根据一个特定的表在一个缓冲区中置换位。假设表中的每个位置(i)上都存在一个值p,函数permute通过将位置p的位移动到位置(i)上来完成对传入的buffer的置换。
要置换密钥,将表Des_Transform(同表1)传给函数permute。必要的旋转操作可以通过调用位操作bit_rot_left来实现。该操作将buffer按照指定的位数向左旋转。每一轮要正确旋转28位的子密钥分组,将表Des_Rotations(同表2)中合适的元素传给bit_rot_left。通过调用permute,并把传入表Des_permuted(同表3),来对每一个子密钥做置换选择。
要加密一个数据块,首先要执行初始置换。为实现这一步,首先调用函数permute并将表Des_Initial(同表4)传入。然后,将数据分为两个32位的分组:lblk以及rblk。回顾一下,加密数据的大部分工作都是将一系列的操作重复执行16轮。每一轮的主要工作都花在计算函数(f)的值上,将值保存在fblk中。
每一轮操作开始时,将对rblk执行一个扩展置换。为了实现这个步骤,将调用函数permute,并把表Des_Expansion(同表5)传入。然后,通过调用位操作bit_xor来计算扩展后的rblk和某个适当的子密钥的异或值。无论是加密还是解密数据,与本轮操作相关的子密钥都需要参与执行。一旦完成了异或计算,将对结果执行一系列的S盒替换操作。Des_Sbox(同表6)定义了8个用于DES算法中的S盒。对于当前fblk中的每个6位分组,第1位和最后1位联合起来确定Des_Sbox中的行号,而中间的4位用来确定列号。最后执行P盒置换来完成函数f的计算。通过调用permute函数并传入表Des_Pbox(同表7)来实现这个步骤。计算出lblk与函数f的值的异或结果,并交换lblk和rblk来结束一轮的操作。
将上述过程重复16次,每轮一次。当全部16轮操作完成后,将rblk拷贝到target的前32位中,将lblk拷贝到之后的32位中(按照要求,最后一轮不交换lblk和rblk)。最终,通过调用permute并把Des_Final(同表8)传入来完成最后的置换操作。
des_encipher的时间复杂度是O(1),因为加密数据块的所有步骤都能在恒定的时间内完成。
des_decipher
函数des_decipher将一个64位的密文分组通过DES算法进行解密。同des_encipher一样,des_decipher实际通过调用des_main来完成解密任务,但这里direction需要设置为decipher。因此,des_decipher的工作方式同des_encipher一样,只是这里的子密钥需要以逆序的方式参与。具体来说,就是在des_main中,针对每一轮i(从0开始计数),参与计算的子密钥为subkeys数组中下标为(15-i)的元素。
des_decipher的时间复杂度为O(1),因为解密数据块中的所有步骤都可以在恒定的时间内完成。
考虑到DES算法中涉及的位操作很多,因此DES算法通常都是在硬件中实现。DES算法中的图表和术语(通过线、框画的流程图,以及诸如S盒、P盒这样的术语)使其更倾向于在硬件中实现,当然,软件实现也有它的价值所在。在软件开发中,通过几种基本的指令操作来帮助实现DES中的各种置换、转换以及替换操作都是很有效的。
des_encipher
函数des_encipher将明文的一个64位的明文分组通过DES算法加密。
由于DES的一个很好的特点是同样的过程既能用来加密数据也能用来解密数据,因此des_encipher只需要简单的调用des_main,而des_decipher同样也只需要调用des_main即可。
函数des_main通过使用其参数direction来确定到参数source提供的数据是明文还是密文。direction参数只是简单地修改子密钥的顺序。
在des_encipher中,direction设置为encipher。
函数des_main()首先检测参数key是否为NULL。这将允许des_encipher的调用者重用上一次调用时计算出来的子密钥。将子密钥数组subkeys声明为static类型。如果key不为NULL,将计算子密钥。
要计算子密钥,可以按照前面介绍过的步骤(计算16个子密钥)来执行。key的转换是通过函数permute来实现的,这里就是根据一个特定的表在一个缓冲区中置换位。假设表中的每个位置(i)上都存在一个值p,函数permute通过将位置p的位移动到位置(i)上来完成对传入的buffer的置换。
要置换密钥,将表Des_Transform(同表1)传给函数permute。必要的旋转操作可以通过调用位操作bit_rot_left来实现。该操作将buffer按照指定的位数向左旋转。每一轮要正确旋转28位的子密钥分组,将表Des_Rotations(同表2)中合适的元素传给bit_rot_left。通过调用permute,并把传入表Des_permuted(同表3),来对每一个子密钥做置换选择。
要加密一个数据块,首先要执行初始置换。为实现这一步,首先调用函数permute并将表Des_Initial(同表4)传入。然后,将数据分为两个32位的分组:lblk以及rblk。回顾一下,加密数据的大部分工作都是将一系列的操作重复执行16轮。每一轮的主要工作都花在计算函数(f)的值上,将值保存在fblk中。
每一轮操作开始时,将对rblk执行一个扩展置换。为了实现这个步骤,将调用函数permute,并把表Des_Expansion(同表5)传入。然后,通过调用位操作bit_xor来计算扩展后的rblk和某个适当的子密钥的异或值。无论是加密还是解密数据,与本轮操作相关的子密钥都需要参与执行。一旦完成了异或计算,将对结果执行一系列的S盒替换操作。Des_Sbox(同表6)定义了8个用于DES算法中的S盒。对于当前fblk中的每个6位分组,第1位和最后1位联合起来确定Des_Sbox中的行号,而中间的4位用来确定列号。最后执行P盒置换来完成函数f的计算。通过调用permute函数并传入表Des_Pbox(同表7)来实现这个步骤。计算出lblk与函数f的值的异或结果,并交换lblk和rblk来结束一轮的操作。
将上述过程重复16次,每轮一次。当全部16轮操作完成后,将rblk拷贝到target的前32位中,将lblk拷贝到之后的32位中(按照要求,最后一轮不交换lblk和rblk)。最终,通过调用permute并把Des_Final(同表8)传入来完成最后的置换操作。
des_encipher的时间复杂度是O(1),因为加密数据块的所有步骤都能在恒定的时间内完成。
des_decipher
函数des_decipher将一个64位的密文分组通过DES算法进行解密。同des_encipher一样,des_decipher实际通过调用des_main来完成解密任务,但这里direction需要设置为decipher。因此,des_decipher的工作方式同des_encipher一样,只是这里的子密钥需要以逆序的方式参与。具体来说,就是在des_main中,针对每一轮i(从0开始计数),参与计算的子密钥为subkeys数组中下标为(15-i)的元素。
des_decipher的时间复杂度为O(1),因为解密数据块中的所有步骤都可以在恒定的时间内完成。
四、DES加密算法的三个原则
混淆:使密文与密钥的关系可能复杂化,使得对手即使获取了许多明文和对应的密文,以及关于密文的一些统计特性,也无法推测密钥。
扩散:让明文中的每一位影响密文中的许多位,后者说让密文中的每一位受明文中的许多的影响。这样可以隐蔽明文的统计特性。当然,理想的情况是让明文中的每一位影响密文中的所有为,或者说让密文中的每一位受明文中所有位的影响。
分组:可以看成经典的电报密码本加密技术的现代传承,其中由密钥来决定电报密码本的选择。一次加密一组数据,密钥长度为一组数据的长度。
五、DES加密算法的特点
DES加密算法产生密钥的方式简单,密钥一般也比较短。
DES加密算法解密速度快,效率很高,适合对大数据量的数据进行加密。
DES加密算法的安全性依赖于密钥的高度保密,通信双方必须有方法能保证安全的分享密钥,并定期更换DES密钥。