首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

DES 加密解密 ( C语言兑现 )

2012-06-27 
DES 加密解密 ( C语言实现 )?Des算法介绍: http://zh.wikipedia.org/wiki/DES维基百科中des算法的介绍很详

DES 加密解密 ( C语言实现 )



?Des算法介绍: http://zh.wikipedia.org/wiki/DES

维基百科中des算法的介绍很详细了.

?

?

1轮的 des 采用 56 位有效的密钥(密钥本来是64位,其中第8,16,24,32,40,48,56,64位不影响结果) 对 64 位(8字节) 数据 进行加密, 加密解密算法是统一算法(过程一样,使用密钥次序不同)。

?

算法过程:

概述:

通过图比较容易 理解

?

DES 加密解密 ( C语言兑现 )

?

① 算法开始对 输入数据进行初始的位置换 , IBM 已经给出置换表(下面大量置换都是查表置换 )置换之后得到初始数据。

{

置换表:

? char table_IP[]????/* 初始置换表 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?
?? };

?? 所以现在查表一位一位置换,比如 :

???原始数据存在 data1-data64 这 64 位中,置换后数据存在 to1 - to64 中:

?? 则有: to1 = data58, to2 = data50, to42 = data42 ... to64 = data7 .

? ?这样就可以得到新数据。

?

}//第一步结束

??????????????

?

② 初始置换后将进行 16 轮的加密过程(16 轮是一样的)<这个过程中初始数据先被分成左右两部分 各 32位 >

? {

???2.1 ?对右边部分进行扩展置换 (通过查表,将32位数据变换为 48 位)

???? 过程如:

?char table_E[]
?= {
????????? 32,? 1,? 2,? 3,? 4,? 5,? 4,? 5,? 6,? 7,? 8,? 9,
????????? 8,? 9, 10, 11, 12, 13,?12, 13, 14, 15, 16, 17,
???????? ?16, 17, 18, 19, 20, 21,?20, 21, 22, 23, 24, 25,
???????? ?24, 25, 26, 27, 28, 29,?28, 29, 30, 31, 32,? 1??
??? };

??? 原始数据存在 data1-data32 这?32 位中,置换后数据存在 to1 - to48 中:

???? 则有: to1 = data32,?? to2 = data1,?? to42 = data2? ... to64 = data1 .

??? 其实其中就是重复去了一些值,将32位扩展到48位。

?

?

?? 2.2 现在得到 48 位扩展数据,将它和这一轮的密钥进行异或运算? 得到还是48位的数据? (密钥怎么得到 ?得到什么样的密钥 ?后面再说)

??

?

?? 2.3 这里是一个很精妙的 S 盒置换 , IBM 提供了8张表,将48位的数据压缩为 32 位

?? { // 这里 也是采用分组的方法 ! 48位分成 8组,每组 6 位压缩后这个分组是 4 位 过程如下:

???? ( S表很大,这里不写出来 ,源码中有 : char table_S[8][64] )

????

???? 从与密钥异或后的数据中中 取出?一个分组??

?????? 比如 第 i? = 1 个分组 为:?1 0 1 0 1 0??? 则 我们先选择 S盒中的 第 1 张表 《 S盒的表选择 》

??????

?????? ?然后再从 第 i 张表中取出 置换值

?????? {

????????? 这个分组中的 第1位和第6为决定所在行 10 则是 第?2 行? (行是:0,1,2,3 行)

??????????这个分组中的 第2-5位决定所在列? 0101 这是???? 第 5 列? (列是:0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f 列)

????????? 则我们可以 从 表 1 选出 第 2 行,第 5 列 的值,是 6

??????? }

?

??????? 6 的二进制值为:0110 这个值就是我们置换后的值 !???????

????

??????

?? }//? S盒 结束

??

?? 2.4 P-盒置换 ,?对S盒产生的 32位数据进行置换。(?和前面的置换是一样的,只是表不同)

??

?? 2.5 将 P 盒置换出来的数据与 左半部分进行置换 。

??

???2.6 将2.5产生的数据放置到左边数据块中。

?

?? 2.7 将左右两部分进行交换。??

?

? }//第二步? 结束循环?

?

?

③ 末置换 ,置换方法和前面的置换方法一样。

?

?

/// 第二步详细图

?


DES 加密解密 ( C语言兑现 )
?

?

?

?

?

每一轮用于异或密钥产生方法:

?

?
DES 加密解密 ( C语言兑现 )
?

?

密钥处理只有 3 步 :

?

①?初始置换(有且只有 1 次)《这里是64位进行置换》

?

② 分成左右两部分进行循环移位

?{

??? 循环只在?有效位中进行循环移位《关键是 :两部分,有效位》???????

?}

?

③ 从 56 有效位 中提取 48 位?《 这里的细节是 56 位 !从置换表中可以开出 》

?

?

?

实现算法:

?

代码用了大量位运算 :

?

关键 一个是取指定位的值 比如 从 data【0】开始取第 37 位 : ( 37 = 0010 0101?) (从 0 位开始)

/// 解释?? 这里的位顺序可能比较奇怪 :? 一个字节 是 8? 位 比如 1000? 1100? 这里 第 0 位 是 1000 中的 1 ,

/// 第 1 位是 1000 中的红色字,以此类推

?

第 37 为则是 : data[4]? 中的 5 位?

所以可以这样计算??? ( data[ k>>3 ]? >> ( 7 - ( k & 0x07 ) ) )&0x01??;

?

其中: data[ k>>3 ]? 得到第 n 个数, ( 7- (? k & 0x07 )) 得到第 m位 ,将这一位移到最低位 和 0x01与就可以得到这个位的值。

?

?

?

?

实现算法中的 函数 和 上图对应

?

---------------------------------------? 密钥? ------------------------------------------------------

//密钥置换
void fun_InitReplacementKey

?

//对密钥进行移位,并存在接下来下面的字节中
void fun_MoveKey

?

?

//对密钥进行压缩置换并保存到指定位置
void fun_ReplacementCompressKey

?

----------------------------------------- 过程函数 -------------------------------------------------

?

//初始置换 ip
void fun_initReplacement

?

//扩展置换
void fun_expandReplacement_32To48

?

//加 密钥 异或
void fun_xor_48

?


// s盒置换
void fun_S_Replacement

?

//P盒置换
void fun_P_Replacement

?

//左右域异或
void fun_xor_32

?

?

?

?

//末置换 fp
void fun_finalReplacement

?

?

------------------------------------------------------------------

?

最后还有几个函数:

?

//设置 密码

void setKey

?

?

//des 加密
char* des

?


// 解密
char * dedes

?

?

?

日志输出控制 宏:

?

//打印过程中 <数据日志>
//#define __LOGDATA__

?

?

//打印过程中 <Debug日志>
//#define __DEBUG__

?

?

//打印过程中<每一轮结果的日志>
//#define __LOG__

?

?

//打印 <结果日志>
//#define __LOGRESULT__

?

?

//打印 <密钥日志>
//#define __LOGKEY__

?

?

具体实现过程在 附件中:

采用c语言在 vs2010 中 编译运行通过

?

?

?

?

热点排行