有关DES的加密流程详解des算法加密流程_lkw23333的博客-CSDN博客_des密钥加密过程

此处只做简略介绍,或者看代码注释

简要流程

(1)输入8位字符明文以及设定8位字符的加密密钥;

(2)将字符串的明文转换为64位的二进制表示;密钥也转换为64位二进制表示;

(3)对64位的密钥进行密钥扩展生16个48位的子密钥;

(4)对64位明文进行ip置换,分成L与R两组各32位;

(5)R经过轮函数F后与L进行异或操作生成新的R,新的L由之前的R代替;

(6)重复上述步骤16次后再进行一次IP逆置换即可得到64位密文;

(7)将加密后64位密文转为16位16进制输出方便显示;

(8)解密与加密步骤相同只是部分操作相反;

总结

整个des算法涉及到的那种晦涩的理论知识并不多所以理解起来很容易。各种操作通过代码实现起来都很ez,理解起来也很ez。就是过程稍微有点繁杂,而且在写代码的过程中不能调试,只能写完了调,这就导致找bug有点痛苦。不过这个过程是有收获的。

#include<stdio.h>
#include<string.h>int IP_Table[64]={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
};
// IP-1置换表
int IPR_Table[64]={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
};// E扩展表
int E_Table[48]={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
};
// PC1置换表
int PC1_Table[56]={57,49,41,33,25,17, 9, 1,58,50,42,34,26,18,10, 2,59,51,43,35,27,19,11, 3,60,52,44,36,63,55,47,39,31,23,15, 7,62,54,46,38,30,22,14, 6,61,53,45,37,29,21,13, 5,28,20,12, 4
};// pc2表
int PC2_Table[48]={14,17,11,24,1,5,3,28,15,6,21,10,23,19,12,4,26,8,16,7,27,20,13,2,41,52,31,37,47,55,30,40,51,45,33,48,44,49,39,56,34,53,46,42,50,36,29,32
};
//  移位表
int LOOP_Table[16]={1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};// S盒
int S_Box[8][4][16]={//S114, 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,//S215, 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,//S310, 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,14,12,11,15, 1,13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,//S47,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,//S52,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,//S612, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,10,15, 4, 2, 7,12, 0, 5, 6, 1,13,14, 0,11, 3, 8,9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,//S74,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,13, 0,11, 7, 4, 0, 1,10,14, 3, 5,12, 2,15, 8, 6,1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,//S813, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11
};//P置换表
int P_Table[32]={16, 7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10,2, 8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25
};//执行des加密
void doDes(int *mingBit, char *ciphertext, int *keyBit);
//拷贝数组
void bitCopy(int *input, int *output, int length);
//做ip置换和逆置换
void doIp(int *array, int length, int *table);
//异或运算
void doXor(int *output, int *input, int length);
//E盒扩展
void doE(int *R, int *eTemp, int length);
//S盒压缩
void doS(int *R, int *eTemp);
//P盒置换
void doP(int *array);
//两个PC表的置换
void doPc_1(int *keyBit, int *output);
void doPc_2(int *iKey, int *C, int *D);
//循环左移动
void lMove(int *C, int *D, int moveBit);
//子密钥生成
void setIkey(int *keyBit, int iKey[16][48]);
//轮函数F
void lunF(int *R, int *iKey);
//字符转位
void charToBit(char *input , int *output, int length);
//位转字符
void bitToChar(int *input, char *output, int length);
//des解密函数
void deDes(char *mingWen,char *ciphertext, char *keyBit);//ip置换根据table确定
void doIp(int *array, int length, int *table){int temp[64] = {0};bitCopy(array, temp, 64);for(int i = 0; i < length; ++i){array[i] = temp[table[i] - 1];}
}//整个程序的异或运算执行函数
void doXor(int *output, int *input, int length){for(int i=0; i<length; ++i){output[i] = output[i] ^ input[i];}
}//E盒扩展 32——>48,方便后面与子密钥异或
void doE(int *R, int *eTemp, int length)
{for(int i = 0; i < length; ++i){eTemp[i] = R[E_Table[i] - 1];}
}//S盒压缩 48——>32
void doS(int *R, int *eTemp)
{int i, x, y;//注意指针的移动步数for(i = 0; i < 8; ++i, eTemp += 6, R += 4){x = eTemp[0]*2 + eTemp[5];y = eTemp[1]*8 + eTemp[2]*4 + eTemp[3]*2 + eTemp[4];//    printf("%d %d\n", x, y);char T = (char)S_Box[i][x][y];charToBit(&T, R, 4);}}
//简单的P盒置换
void doP(int *array)
{int temp[32] = {0};bitCopy(array, temp, 32);for(int i = 0; i < 32; ++i){array[i] = temp[P_Table[i] - 1];}
}
//密钥的pc_1表置换,剔除奇偶校验位
void doPc_1(int *keyBit, int *output){for(int i = 0; i < 56; ++i){output[i] = keyBit[PC1_Table[i] - 1];}
}//合并c,d两部分进行pc_2的置换 56——>48
void doPc_2(int *iKey, int *C, int *D){int temp[56]={0};bitCopy(C, temp, 28);bitCopy(D, temp+28, 28);for(int i=0; i<48; ++i){iKey[i] = temp[PC2_Table[i]-1];}
}//密钥循环左移
void lMove(int *C, int *D, int moveBit){int temp[28] = {0};bitCopy(C, temp, 28);bitCopy(temp+moveBit, C, 28-moveBit);bitCopy(temp, C+28-moveBit, moveBit);bitCopy(D, temp, 28);bitCopy(temp+moveBit, D, 28-moveBit);bitCopy(temp, D+28-moveBit, moveBit);}//生成子密钥
void setIkey(int *keyBit, int iKey[16][48])
{int temp[56]={0};int C[28];int D[28];doPc_1(keyBit, temp);//先做pc1剔除校验位,在拆成两组bitCopy(temp, C, 28);bitCopy(temp+28, D, 28);for(int i=0; i<16; ++i){lMove(C, D, LOOP_Table[i]);doPc_2(iKey[i], C, D);}
}void lunF(int *R, int *iKey)
{int eTemp[48]={0};//E盒扩展doE(R, eTemp, 48);//和密钥异或doXor(eTemp, iKey, 48);//S盒压缩doS(R, eTemp);//P盒压缩doP(R);}//字符转换为位方便加密
void charToBit(char *input , int *output, int length)
{int i=0;for(i=0;i < length;i++){output[i]=(input[i/8]>>(i%8))&1;}}
//位转字符,复原
void bitToChar(int *input, char *output, int length)
{int i;for(i=0;i<(length/8);i++){output[i]=0;}for(i=0;i<length;i++){output[i/8]|= input[i]<<(i%8);}}//整个程序,拷贝用的函数
void bitCopy(int *input, int *output, int length)
{int i;for(i = 0; i < length; ++i){output[i] = input[i];}
}//执行DES
void doDes(int *mingBit, char *ciphertext, int *keyBit){int *L = &mingBit[0];int *R = &mingBit[32];int temp[32] = {0};//借助temp实现L,R的赋值int iKey[16][48] = {0};//ip置换doIp(mingBit, 64, IP_Table);//生成子密钥setIkey(keyBit, iKey);//16轮跑起来for(int i=0; i<16; ++i){bitCopy(R, temp, 32);//执行F函数lunF(R, iKey[i]);//与L异或doXor(L, R, 32);bitCopy(L, R, 32);bitCopy(temp, L, 32);}//IP逆置换doIp(mingBit, 64, IPR_Table);//将密文转成16进制显示bitToHex(ciphertext, mingBit, 64);
}
//解密函数,与des差不多
void deDes(char *mingWen,char *ciphertext, char *keyBit)// DES轮解密算法;
{int cBit[64]={0};int *L=&cBit[0];int *R=&cBit[32];int temp[32]={0};int iKey[16][48] = {0};hexToBit(cBit, ciphertext, 64);doIp(cBit, 64, IP_Table);setIkey(keyBit, iKey);//密钥从后往前,L,R与DES相反for(int i=15;i>=0;i--){bitCopy(L, temp, 32);lunF(L, iKey[i]);doXor(R, L, 32);bitCopy(R, L, 32);bitCopy(temp, R, 32);}doIp(cBit, 64, IPR_Table);printf("\n");bitToChar(cBit, mingWen, 64);}void bitToHex(char *output, int *input, int length)
{int i;for(i=0;i<length/4;i++){output[i]=0;}for(i=0;i<length/4;i++){output[i]=input[4*i]+input[4*i+1]*2+input[4*i+2]*4+input[4*i+3]*8;if(output[i]%16>9){output[i]=output[i]%16+'7';}elseoutput[i]=output[i]%16+'0';}}void hexToBit(int *output, char *input,int length)
{int i;for(i=0;i<length;i++){if(input[i/4]<='9'){output[i]=((input[i/4]-'0')>>(i%4))&0x01;}else{output[i]=((input[i/4]-'7')>>(i%4))&0x01;}}
}int main(){int mingBit[64] = {0};char ciphertext[16];int keyBit[64] = {0};char mingWen[8]="lkw23333";char key[8]="ssssssss";char deKey[8];printf("明文为:\n");for(int i = 0; i < 8; ++i){printf("%c", mingWen[i]);}printf("\n");charToBit(mingWen, mingBit, 64);charToBit(key, keyBit, 64);doDes(mingBit, ciphertext, keyBit);printf("加密后:\n");for(int i = 0; i < 16; ++i){printf("%c", ciphertext[i]);}printf("\n");printf("请输入密钥解密:");gets(deKey);charToBit(deKey, keyBit, 64);deDes(mingWen, ciphertext, keyBit);printf("明文为:\n");for(int i = 0; i < 8; ++i){printf("%c", mingWen[i]);}printf("\n");return 0;
}

DES算法C语言实现相关推荐

  1. DES算法 C语言实现

    DES算法C语言实现 算法概述 DES算法是一种对称块加密方法,加密和解密都使用一个长度为64位的密钥.以64位为一个分组长度,对于每个分组,通过置换.Feistel轮函数.子密钥生成等一系列操作,输 ...

  2. java c语言 实现des算法_C语言实现DES算法

    /*------------------------------------------------------- Data Encryption Standard 56位密钥加密64位数据 2011 ...

  3. des算法c语言运行成功截图,求助攻:C语言DES算法的实现程序有问题

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #include //初始置换表IP int IP_Table[64] = { 57,49,41,33,25,17,9 ...

  4. c语言des算法实验报告,C语言实现DES算法实验报告解析.doc

    C语言实现DES算法实验报告解析 xx工程大学 实验报告 (2015-2016学年第一学期) 报告题目: DES加密算法 课程名称: 密码学B 任课教员: 专 业: 学 号: 姓 名: 二O一六年一月 ...

  5. c语言des算法实验报告,c语言实现des算法des加密算法实验报告

    c语言实现des算法des加密算法实验报告 (23页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 xx 工程大学工程大学实验报告实验报告 ...

  6. DES算法代码实现(C语言)

    实验内容: 通过C语言模拟DES算法的整个加密过程 初始明文(64位),首先通过IP置换表进行置换,然后将置换后的结果分成左半部分L0(32位)和右半部分R0(32位),右半部分R0直接进行交换为下一 ...

  7. 【安全算法之DES】DES算法(支持ECB/CBC模式)的C语言源码实现

    [安全算法之DES]DES算法(支持ECB/CBC模式)的C语言源码实现 概述 头文件定义 C语言版本的实现源码 数据分组模式:ECB模式和CBC模式 测试用例 github仓库 更多参考链接 概述 ...

  8. des实验报告c语言实现,C语言实现DES算法实验报告

    <C语言实现DES算法实验报告>由会员分享,可在线阅读,更多相关<C语言实现DES算法实验报告(29页珍藏版)>请在人人文库网上搜索. 1.xx工程大学实验报告(2015-20 ...

  9. 基于C语言实现的DES算法

    Information Security Assignment 1 - DES 算法实现 算法原理概述 DES 是一种典型的块加密方法:它以 64 位为分组长度,64 位一组的明文作为算法的输入,通过 ...

最新文章

  1. 用yacc编写的算术运算计算器_详细的mac计算器操作技巧+快捷键分享
  2. oracle ORA-00604和BadImageFormatException的解决方法
  3. P4899 [IOI2018] werewolf 狼人(kruskal 重构树 + 主席树)
  4. jzoj2292-PPMM【模拟,堆】
  5. 出现“cannot identify image file /.DS_Store'”问题解决的办法
  6. 图论 —— 网络流 —— 最小割 —— 平面图与对偶图
  7. OAuth2.0_介绍_Spring Security OAuth2.0认证授权---springcloud工作笔记137
  8. iTunes Connect(一) —— iOS应用上架到AppStore
  9. 相机标定(六)—— 张正友标定法
  10. 01 ZooKeeper初探
  11. 华为推送服务回执证书即将到期,尽快更新
  12. 淘宝数据魔方技术架构解析阅读心得
  13. Technorati Grabber:获得您的Technorati排名和权限
  14. java麻将算法_Java实现的麻将胡牌算法
  15. wsl 1 ubuntu 安装图像化界面
  16. PMP项目管理培训总结
  17. 以太坊签名,验证签名, EIP712domain Permit授权并转账
  18. uniapp PDA广播扫码
  19. javaScript 在表格中序号实现自增
  20. Safari浏览器导出数据(excel)文件名乱码, 后缀不对的问题

热门文章

  1. 【阿里云 Linux 服务器】购买 Linux 到项目部署过程中遇到的问题,部署 SpringBoot 项目到服务器上,在手机上安装 Android 程序进行测试
  2. linux离线安装rjava,无法在ubuntu系统上安装rJava
  3. c code first mysql_Code First for MySql命令操作
  4. matlab 表格控件,[转载]matlab读取excel数据并显示在excel(activex控件)中
  5. SLAM:SLAM相机简介、SLAM五步流程简介(VO+BEO+LCD+M)之详细攻略
  6. AI:2020年6月21日北京智源大会演讲分享之09:20-09:40黄铁军教授《智源进展报告》
  7. BigData之Spark:Spark计算引擎的简介、下载、经典案例之详细攻略
  8. ML之Hog_HammingDistance:基于Hog特征提取“RGB”图像的768个值的单向vector利用汉明距离算法进行判别
  9. 成功解决python\ops\seq2seq.py TypeError: ms_error() got an unexpected keyword argument 'labels'
  10. ML之Xgboost:利用Xgboost模型(7f-CrVa+网格搜索调参)对数据集(比马印第安人糖尿病)进行二分类预测