DES 实现
原理
加密

置换:

IP逆置换:

迭代:

PC-1置换:

PC-2置换:

子秘钥的生成:

加密函数f:



解密

代码
// C语言实现
#include<stdio.h>
#include<string.h>
/*
参考链接:https://blog.csdn.net/zidane_2014/article/details/37988657
*/
int IP_Table[64] = { //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 };
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 };
int P_Table[32] = { // P 盒
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 };
int IPR_Table[64] = { //逆IP置换矩阵
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 };
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 };
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 S_Box[8][4][16] = { //8个S盒 三维数组
// 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, 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,
// S4
7, 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,
// S5
2, 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,
// S6
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 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,
// S7
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 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,
// S8
13, 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
};
static void CharToBit(const char input[], int output[], int bits)//把CHAR转换为INT
{
int i, j;
for (j = 0; j < 8; j++)
{
for (i = 0; i < 8; i++)
{
output[7 * (j + 1) - i + j] = (input[j] >> i) & 1;
}
}
};
static void BitToChar(const int intput[], char output[], int bits)//把INT转换为CHAR
{
int i, j;
for (j = 0; j < 8; j++)
{
for (i = 0; i < 8; i++)
{
output[j] = output[j] * 2 + intput[i + 8 * j];
}
}
};
static void Xor(int* INA, int* INB, int len)//异或操作
{
int i;
for (i = 0; i < len; i++)
{
*(INA + i) = *(INA + i) ^ *(INB + i);
}
};
static void IP(const int input[64], int output[64], int table[64])//初始IP置换
{
int i;
for (i = 0; i < 64; i++)
{
output[i] = input[table[i] - 1];//减1操作不可少!!
}
};
static void E(const int input[32], int output[48], int table[48])//E扩展
{
int i;
for (i = 0; i < 48; i++)
{
output[i] = input[table[i] - 1];
}
};
static void P(const int input[32], int output[32], int table[32])//P置换
{
int i;
for (i = 0; i < 32; i++)
{
output[i] = input[table[i] - 1];
}
};
static void IP_In(const int input[64], int output[64], int table[64])//逆IP
{
int i;
for (i = 0; i < 64; i++)
{
output[i] = input[table[i] - 1];
}
};
static void PC_1(const int input[64], int output[56], int table[56])//PC_1
{
int i;
for (i = 0; i < 56; i++)
{
output[i] = input[table[i] - 1];
}
};
static void PC_2(const int input[56], int output[48], int table[48])//PC_2
{
int i;
for (i = 0; i < 48; i++)
{
output[i] = input[table[i] - 1];
}
};
static void S(const int input[48], int output[32], int table[8][4][16])//S盒压缩
{
int i = 0;
int j = 0;
int INT[8];
for (; i < 48; i = i + 6)
{
INT[j] = table[j][(input[i] << 1) + (input[i + 5])][(input[i + 1] << 3) + (input[i + 2] << 2) + (input[i + 3] << 1) + (input[i + 4])];
j++;
}
for (j = 0; j < 8; j++)
{
for (i = 0; i < 4; i++)
{
output[3 * (j + 1) - i + j] = (INT[j] >> i) & 1;
}
}
};
static void F_func(int input[32], int output[32], int subkey[48])//完成DES算法轮变换
{
int len = 48;
int temp[48] = { 0 };
int temp_1[32] = { 0 };
E(input, temp, E_Table);
Xor(temp, subkey, len);
S(temp, temp_1, S_Box);
P(temp_1, output, P_Table);
};
static void RotateL(const int input[28], int output[28], int leftCount)//完成子密钥扩展的循环左移
{
int i;
int len = 28;
for (i = 0; i < len; i++)
{
output[i] = input[(i + leftCount) % len];
}
};
static void subKey_fun(const int input[64], int Subkey[16][48])//完成16轮子密钥生成
{
int loop = 1, loop_2 = 2;
int i, j;
int c[28], d[28];
int pc_1[56] = { 0 };
int pc_2[16][56] = { 0 };
int rotatel_c[16][28] = { 0 };
int rotatel_d[16][28] = { 0 };
PC_1(input, pc_1, PC1_Table);
for (i = 0; i < 28; i++)
{
c[i] = pc_1[i];
d[i] = pc_1[i + 28];
}
int leftCount = 0;
for (i = 1; i < 17; i++)
{
if (i == 1 || i == 2 || i == 9 || i == 16)
{
leftCount += loop;
RotateL(c, rotatel_c[i - 1], leftCount);
RotateL(d, rotatel_d[i - 1], leftCount);
}
else
{
leftCount += loop_2;
RotateL(c, rotatel_c[i - 1], leftCount);
RotateL(d, rotatel_d[i - 1], leftCount);
}
}
for (i = 0; i < 16; i++)
{
for (j = 0; j < 28; j++)
{
pc_2[i][j] = rotatel_c[i][j];
pc_2[i][j + 28] = rotatel_d[i][j];
}
}
for (i = 0; i < 16; i++)
{
PC_2(pc_2[i], Subkey[i], PC2_Table);
}
};
//DES加密运算
static void DES_Efun(char input[8], char key_in[8], int output[64])
{
int Ip[64] = { 0 };//存储初始置换后的矩阵
int output_1[64] = { 0 };
int subkeys[16][48];
int chartobit[64] = { 0 };
int key[64];
int l[17][32], r[17][32];
CharToBit(input, chartobit, 8);//正确,转换为64个二进制数的操作正确!
IP(chartobit, Ip, IP_Table);//正确,IP初始置换!
CharToBit(key_in, key, 8);//正确!
subKey_fun(key, subkeys);//正确!
for (int i = 0; i < 32; i++)
{
l[0][i] = Ip[i];
r[0][i] = Ip[32 + i];
}
for (int j = 1; j < 16; j++)//前15轮的操作
{
for (int k = 0; k < 32; k++)
{
l[j][k] = r[j - 1][k];
}
F_func(r[j - 1], r[j], subkeys[j - 1]);
Xor(r[j], l[j - 1], 32);
}
int t = 0;
for (t = 0; t < 32; t++)//最后一轮的操作
{
r[16][t] = r[15][t];
}
F_func(r[15], l[16], subkeys[15]);
Xor(l[16], l[15], 32);
for (t = 0; t < 32; t++)
{
output_1[t] = l[16][t];
output_1[32 + t] = r[16][t];
}
IP_In(output_1, output, IPR_Table);
};
//完成DES解密运算
static void DES_Dfun(int input[64], char key_in[8], char output[8])
{
int Ip[64] = { 0 };//存储初始置换后的矩阵
int output_1[64] = { 0 };
int output_2[64] = { 0 };
int subkeys[16][48];
int chartobit[64] = { 0 };
int key[64];
int l[17][32], r[17][32];
IP(input, Ip, IP_Table);//正确,IP初始置换!
CharToBit(key_in, key, 8);//正确!
subKey_fun(key, subkeys);//正确!
for (int i = 0; i < 32; i++)
{
l[0][i] = Ip[i];
r[0][i] = Ip[32 + i];
}
for (int j = 1; j < 16; j++)//前15轮的操作
{
for (int k = 0; k < 32; k++)
{
l[j][k] = r[j - 1][k];
}
F_func(r[j - 1], r[j], subkeys[16 - j]);
Xor(r[j], l[j - 1], 32);
}
int t = 0;
for (t = 0; t < 32; t++)//最后一轮的操作
{
r[16][t] = r[15][t];
}
F_func(r[15], l[16], subkeys[0]);
Xor(l[16], l[15], 32);
for (t = 0; t < 32; t++)
{
output_1[t] = l[16][t];
output_1[32 + t] = r[16][t];
}
IP_In(output_1, output_2, IPR_Table);
BitToChar(output_2, output, 8);
}; int main()
{
int output[64] = { 0 };
char MIN[9] = { 0 }; // 明文
char MI[9] = { 0 }; //秘钥
printf("请输入明文(8个字符):");
gets(MIN);
printf("请输入秘钥(8个字符):");
gets(MI);
DES_Efun(MIN, MI, output);
printf("密文如下:\n");
for (int i = 0; i < 64; i++)
{
printf("%d", output[i]);
if ((i + 1) % 4 == 0)
printf("\n");
}
printf("\n");
printf("解密功能\n");
DES_Dfun(output, MI, MIN);
printf("明文如下:\n");
for (int i = 0; i < 8; i++)
{
printf("%c", MIN[i]);
}
printf("\n");
system("pause");
return 0;
}
DES 实现的更多相关文章
- 在.NET Core 里使用 BouncyCastle 的DES加密算法
.NET Core上面的DES等加密算法要等到1.2 才支持,我们可是急需这个算法的支持,文章<使用 JavaScriptService 在.NET Core 里实现DES加密算法>需要用 ...
- 使用 JavaScriptService 在.NET Core 里实现DES加密算法
文章<ASP.NET Core love JavaScript>和<跨平台的 NodeJS 组件解决 .NetCore 不支持 System.Drawing图形功能的若干问题> ...
- [C#] 简单的 Helper 封装 -- SecurityHelper 安全助手:封装加密算法(MD5、SHA、HMAC、DES、RSA)
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace Wen. ...
- 4、DES和RSA简介
DES是分组加密算法,速度快,使用单一密钥,加密解密都使用同一个密钥,一般用于大量数据加密,目前处于半淘汰状态. RSA算法是流式加密算法,速度慢,但是使用成对的密钥,加密解密使用不同的密钥,有利于保 ...
- Android数据加密之Des加密
前言: 端午节前有个同事咨询我有关Android DES加密的相关实现,简单的实现了一下,今天来总结一下. 其他几种加密方式: Android数据加密之Rsa加密 Android数据加密之Aes加密 ...
- 密码学应用(DES,AES, MD5, SHA1, RSA, Salt, Pkcs8)
目录 一.数据加密标准 - Data Encryption Standard(DES) 二.高级加密标准 - Advanced Encryption Standard(AES) 三.消息摘要算法第五版 ...
- When I see you again(加密原理介绍,代码实现DES、AES、RSA、Base64、MD5)
关于网络安全的数据加密部分,本来打算总结一篇博客搞定,没想到东西太多,这已是第三篇了,而且这篇写了多次,熬了多次夜,真是again and again.起个名字:数据加密三部曲,前两部链接如下: 整体 ...
- Java 加解密 AES DES TripleDes
package xxx.common.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.crypt ...
- .NET和JAVA中BYTE的区别以及JAVA中“DES/CBC/PKCS5PADDING” 加密解密在.NET中的实现
场景:java 作为客户端调用已有的一个.net写的server的webservice,输入string,返回字节数组. 问题:返回的值不是自己想要的,跟.net客户端直接调用总是有差距 分析:平台不 ...
- php使用openssl进行Rsa长数据加密(117)解密(128) 和 DES 加密解密
PHP使用openssl进行Rsa加密,如果要加密的明文太长则会出错,解决方法:加密的时候117个字符加密一次,然后把所有的密文拼接成一个密文:解密的时候需要128个字符解密一下,然后拼接成数据. 加 ...
随机推荐
- Ubuntu16.04下升级Python到3.7
本帖从IT老兵博客学习得知: 本帖前提: 开发一个Python的系统,需要安装Python3.6以上的版本,由于使用的操作系统是Ubuntu16.04,默认带的Python是2.7.12和3.5,不满 ...
- spark-1-架构设计&基本流程
Spark运行架构包括: (1)集群资源管理器(Cluster Manager) (2)运行作业任务的工作节点(Worker Node) (3)每个应用的任务控制节点(Driver)和每个工作节点上负 ...
- Web前后端:如何分离,如何解耦?
摘要:在本文中我们一起来探讨一下为什么要在软件开发中进行前后端的分离,如何做到前后端分离,如何解耦. 简单地说,就是要把复杂的问题简单化,把一个从0到N的问题转化为N个0到1的问题.另一个相近的说法就 ...
- React踩坑笔记 —— React
Webpack提供了自己的导入方式require.include,但同时也支持commonjs规范或AMD规范的require语法,而Node.js使用的就是common.js,ES6的语法Impor ...
- 拜托,别再问我怎么自学 Java 了!和盘托出
假如有那么残酷的一天,我不小心喝错了一瓶药,一下子抹掉了我这十多年的编程经验,把我变成了一只小白.我想自学 Java,并且想要找到一份工作,我预计需要 6 个月的时间,前提条件是每天都处于高效率的学习 ...
- 实验 6:OpenDaylight 实验——OpenDaylight 及 Postman 实现流表下发
一.实验目的 熟悉 Postman 的使用:熟悉如何使用 OpenDaylight 通过 Postman 下发流表. 二.实验任务 流表有软超时和硬超时的概念,分别对应流表中的 idle_timeou ...
- JS判断PC操作系统版本
var version = navigator.userAgent; console.log(version); //"Mozilla/5.0 (Windows NT 10.0; WOW64 ...
- win10的cortana搜索显示空白
解决方法:重置应用 问题原因:待查明 然后,我们往下拉
- 单调队列优化题:最大数(P1198)
题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制:不超过当前数列的长度.(L>0) ...
- 【原创】xenomai内核解析--双核系统调用(二)--应用如何区分xenomai/linux系统调用或服务
版权声明:本文为本文为博主原创文章,转载请注明出处.如有错误,欢迎指正. 1. 引出问题 上一篇文章xenomai内核解析--双核系统调用(一)以X86处理器为例,分析了xenomai内核调用的流程, ...