DES加解密过程及其C语言实现

1 DES加解密原理

DES算法为密码体制中的对称密码体制,又被称为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。明文按64位进行分组,密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位,使得每个密钥都有奇数个1)分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。其入口参数有三个:key、data、mode。key为加密解密使用的密钥,data为加密解密的数据,mode为其工作模式。当模式为加密模式时,明文按照64位进行分组,形成明文组,key用于对数据加密,当模式为解密模式时,key用于对数据解密。实际运用中,密钥只用到了64位中的56位,这样才具有高的安全性。

1.1 DES算法总体描述及流程图

DES是一个分组加密算法,它以64位为分组对数据加密。64位一组的明文从算法的一端输入,64位的密文从另一段输出。它是一个对称算法:加密和解密用的是同一个算法。密钥通常表示为64位的数,但每个第8位都用作奇偶校验,可以忽略,所以密钥长度为56位。密钥可以是任意的56位的数,且可在任意的时候改变。
对于任意的加密方案,总有两个输入:明文和密钥。DES的明文长为64位,密钥长为56位。明文的处理一般经过三个阶段:首先,64位的明文经过初始置换(IP)而被重新排列。然后经历16轮相同函数的作用,每轮作用都有置换和代替。最后一轮迭代的输出有64位,它是输入明文和密钥的函数。其左半部分和右半部分互换产生预输出。最后预输出再被与初始置换(IP)互逆的置换产生64位的密文。
DES算法只不过是加密的两个基本技术——混乱和扩散的组合,即先代替后置换,它基于密钥作用于明文,这是一轮(round),DES在明文分组上实施16轮相同的组合技术。如下图所示:
DES加解密过程及其C语言实现_第1张图片
图1 DES算法总体描述
DES使得用相同的函数来加密或解密每个分组成为可能,二者唯一的不同就是密钥的次序相反。

1.2 DES加解密算法原理

DES对64位明文分组进行操作。通过一个初始置换,将明文分组分成左半部分和右半部分,各32位长。然后进行16轮完全相同的运算,这些运算被称为函数 f,在运算过程中数据与密钥结合。经过16轮后,左、右半部分合在一起经过一个末置换(初始置换的逆置换),算法就完成了。
在每一轮中,密钥位移位,然后再从密钥的56位中选出48位。通过一个扩展置换将数据的右半部分扩展成48位,并通过一个异或操作与48位密钥结合,通过 8个S盒将这48位替代成新的32位数据,再将其置换一次。这四步运算构成了函数f。然后,通过另一个异或运算,函数f的输出与左半部分结合,其结果即成为新的左半部分。将该操作重复16次,便实现了DES的16轮运算。一轮DES如下图所示:
DES加解密过程及其C语言实现_第2张图片
图2 DES算法一轮迭代的过程

假设Bi是第i次迭代的结果,Li和Ri是Bi的左半部分和右半部分,Ki是第i轮的48位密钥,且f是实现代替、置换及密钥异或等运算的函数,那么每一轮就是:
Li=Ri-1
Ri=Li-1⊕f(Ri-1,Ki)

2 程序代码
#include <iostream> 
#include <fstream> 
using namespace std;

const static char ip[] = {
                      //初始置换     
	58, 50, 42, 34, 26, 18, 10,  2,    
	60, 52, 44, 36, 28, 20, 12,  4,    
	62, 54, 46, 38, 30, 22, 14,  6,  
	64, 56, 48, 40, 32, 24, 16,  8,   
	57, 49, 41, 33, 25, 17,  9,  1,   
	59, 51, 43, 35, 27, 19, 11,  3,   
	61, 53, 45, 37, 29, 21, 13,  5,   
	63, 55, 47, 39, 31, 23, 15,  7  };  
	

const static char fp[] = {
                     //末置换      
	40, 8, 48, 16, 56, 24, 64, 32,   
	39, 7, 47, 15, 55, 23, 63, 31,  
	38, 6, 46, 14, 54, 22, 62, 30,  
	37, 5, 45, 13, 53, 21, 61, 29,   
	36, 4, 44, 12, 52, 20, 60, 28, 
    35, 3, 43, 11, 51, 19, 59, 27,  
	34, 2, 42, 10, 50, 18, 58, 26, 
    33, 1, 41,  9, 49, 17, 57, 25 };

const static char sbox[8][64] = {
               //s_box   
/* S1 */      
	14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,  
	0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,  
	4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,    
	15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,     
/* S2 */     
    15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
	3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,  
	0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,  
	13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,    
/* S3 */     
    10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,  
	13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5

你可能感兴趣的:(密码学篇)