详解DES算法原理与实现(3)

考虑到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),因为解密数据块中的所有步骤都可以在恒定的时间内完成。

示例1:数据加密的头文件(DES算法和RSA算法通用头文件)

/*encrypt.h*/
#ifndef ENCRYPT_H
#define ENCRYPT_H

/*在一个安全实现中,Huge 最少要400位10进制数字*/
typedef unsigned long Huge;

/*为RSA公钥定义一个数据结构*/
typedef struct RsaPubKey_
{
    Huge e;
    Huge n;
}RsaPubkey;

/*为RSA私钥定义一个数据结构*/
typedef struct RsaPriKey_
{
    Huge d;
    Huge n;
}RsaPriKey;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/f623b421ca1b32ccaf22f3f01c926f02.html