吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3021|回复: 13
收起左侧

[C&C++ 原创] DES算法的C语言实现

  [复制链接]
LegendSaber 发表于 2021-10-24 12:40
本帖最后由 LegendSaber 于 2021-10-24 12:52 编辑

       曾经学习DES算法时候写过的一份C语言实现的DES加解密算法。现在提供给大家参考
       首先,由于DES是在比特层面对输入进行加密的。所以,首先需要做到将输入的字符与其二进制形式的互相转换,这部分代码在CChar中实现
[C] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include "CChar.h"
 
void CharToBit(char input[], char output[])
{
        int i = 0, j = 0, k = 0;
         
        for (i = 0; i < 8; i++)
        {
                for (j = 0; j < 8; j++)
                {
                        k = 7 - j;
                        output[i * 8 + j] = (input[i] >> k) & 0x1;
                }
        }
}
 
void BitToChar(char input[], char output[])
{
        int i = 0, j = 0, k = 0;
 
        for (i = 0; i < 8; i++)
        {
                for (j = 0; j < 8; j++)
                {
                        k = 7 - j;
                        output[i] |= (input[i * 8 + j] << k);
                }
        }
}

         其次,为了完成DES加密需要用到的密钥以及置换表等等这部分内容在table.h中定义
[C] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
#ifndef __MY_TABLE_
#define __MY_TABLE_
 
//存储程序所需要的表与密钥
 
//初始置换表IP
const char IP_Table[64] = { 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, 
                            56,48,40,32,24,16,8,0, 
                            58,50,42,34,26,18,10,2, 
                            60,52,44,36,28,20,12,4, 
                            62,54,46,38,30,22,14,6};  
//逆初始置换表IP^-1 
const char IP_1_Table[64] = { 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, 
                              32,0,40,8,48,16,56,24};
//扩展表E
const char E_Table[48] = { 31, 0, 1, 2, 3, 4,
                           3, 4, 5, 6, 7, 8,
                           7, 8, 9, 10, 11, 12,
                           11, 12, 13, 14, 15, 16,
                           15, 16, 17, 18, 19, 20,
                           19, 20, 21, 22, 23, 24,
                           23, 24, 25, 26, 27, 28,
                           27, 28, 29, 30, 31, 0};
//置换表P
const char P_Table[32] = { 15, 6, 19, 20, 11, 27, 16,
                           0, 14, 22, 25, 4, 17, 30, 9,
                           1, 7, 23, 13, 31, 26, 2, 8,
                           18, 12, 29, 5, 21, 10, 3, 24};
//S盒
const char S[8][4][16] =
                {
                    //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 
                    {{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}},
                    //S3 
                    {{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}}, 
                    //S4 
                    {{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}}, 
                    //S5 
                    {{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}}, 
                    //S6 
                    {{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}}, 
                    //S7 
                    {{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}}, 
                    //S8 
                    {{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}}
                };
 
//置换选择1        
int PC_1[56] = { 56,48,40,32,24,16,8, 
                 0,57,49,41,33,25,17, 
                 9,1,58,50,42,34,26, 
                 18,10,2,59,51,43,35, 
                 62,54,46,38,30,22,14, 
                 6,61,53,45,37,29,21, 
                 13,5,60,52,44,36,28, 
                 20,12,4,27,19,11,3}; 
   
//置换选择2 
int PC_2[48] = { 13,16,10,23,0,4,2,27, 
                 14,5,20,9,22,18,11,3, 
                 25,7,15,6,26,19,12,1, 
                 40,51,30,36,46,54,29,39, 
                 50,44,32,46,43,48,38,55, 
                 33,52,45,41,49,35,28,31};
                 
//循环左移的位数
const char RoundLeft[16] = {1, 1, 2, 2,
                            2, 2, 2, 2,
                            1, 2, 2, 2,
                            2, 2, 1, 1};
//加密密钥                     
const char cKey[9] = {"12345678"};
char bKey[56] = { 0 };
//IV向量
char cIV[9] = {"IVVector"};
#endif

         最后就是在主函数中对输入进行16轮的DES加密
[C] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#include <cstdio>
#include <cstring>
#include "table.h"
#include "CChar.h"
 
void DESAlgorithm(char cOrigData[]);        //DES算法主体
//对左边32比特进行加密
void XOREncryptLeft(char cLeftChar[], char cRightChar[], int iIndex);
void InitBitKey();        //将密钥初始化为比特形式且进行置换       
void EncryptByCBC(char cOrigData[], char cOrigData2[]);        //采用CBC模式加密
void EncryptByCFB(char cOrigData[], char cOrigData2[]); //采用CFB模式加密
 
int main()
{
        char cOrigData[9] = {"1900Code"};
        char cOrigData2[9] = {"I 1900"};
         
        printf("加密前的数据: %s %s\n", cOrigData, cOrigData2);
         
        EncryptByCBC(cOrigData, cOrigData2);
        EncryptByCFB(cOrigData, cOrigData2);
         
        getchar();
        return 0;
}
 
void EncryptByCFB(char cOrigData[], char cOrigData2[])
{
        InitBitKey();
        DESAlgorithm(cIV);
         
        for (int i = 0; i < 9; i++) cOrigData[i] ^= cIV[i];
        printf("CFB模式加密后的数据:%s ", cOrigData);
         
        InitBitKey();
        DESAlgorithm(cOrigData);
         
        for (int i = 0; i < 9; i++) cOrigData2[i] ^= cOrigData[i];
        printf("%s\n", cOrigData2);
         
         
        for (int i = 0; i < 9; i++) cOrigData2[i] ^= cOrigData[i];
        InitBitKey();
        DESAlgorithm(cOrigData);
        for (int i = 0; i < 9; i++) cOrigData[i] ^= cIV[i];
        printf("CFB模式解密的数据:%s %s\n", cOrigData, cOrigData2);
        InitBitKey();
        DESAlgorithm(cIV);
}
 
void EncryptByCBC(char cOrigData[], char cOrigData2[])
{
        InitBitKey();
        for (int i = 0; i < 9; i++) cOrigData[i] ^= cIV[i];
        DESAlgorithm(cOrigData);
 
        InitBitKey();
        for (int i = 0; i < 9; i++) cOrigData2[i] ^= cOrigData[i];
        DESAlgorithm(cOrigData2);
        printf("CBC模式加密后结果: %s %s\n", cOrigData, cOrigData2);
         
        InitBitKey();
        DESAlgorithm(cOrigData2);
        for (int i = 0; i < 9; i++) cOrigData2[i] ^= cOrigData[i];
         
        InitBitKey();
        DESAlgorithm(cOrigData);
        for (int i = 0; i < 9; i++) cOrigData[i] ^= cIV[i];
        printf("CBC模式解密后的数据: %s %s\n", cOrigData, cOrigData2);
}
 
void DESAlgorithm(char cOrigData[])
{
        char cLeft[32] = { 0 }, cRight[32] = { 0 }, cOrigChar[64] = { 0 };
        char cTmp = 0, cOrigCpyChar[64] = { 0 };
 
        CharToBit(cOrigData, cOrigChar);
         
        memset(cOrigCpyChar, 0, sizeof(cOrigCpyChar));
        memcpy(cOrigCpyChar, cOrigChar, 64);        //进行初始置换
        for (int i = 0; i < 64; i++)
        {
                cOrigChar[i] = cOrigCpyChar[IP_Table[i]];
        }
         
        for (int i = 0; i < 32; i++)
        {
                cLeft[i] = cOrigChar[i];
                cRight[i] = cOrigChar[32 + i];
        }
         
        for (int i = 0; i < 16; i++)        //进行16轮的加密
        {
                XOREncryptLeft(cLeft, cRight, i);
                 
                //除最后一轮,交换左右两边的比特
                if (i < 15)
                {
                        for (int j = 0; j < 32; j++)
                        {
                                cTmp = cLeft[j];
                                cLeft[j] = cRight[j];
                                cRight[j] = cTmp;
                        }
                }
        }
         
        for (int i = 0; i < 32; i++)
        {
                cOrigChar[i] = cLeft[i];
                cOrigChar[32 + i] = cRight[i];
        }
 
        memset(cOrigCpyChar, 0, sizeof(cOrigCpyChar));
        memcpy(cOrigCpyChar, cOrigChar, 64);        //进行逆初始置换
        for (int i = 0; i < 64; i++)
        {
                cOrigChar[i] = cOrigCpyChar[IP_1_Table[i]];
        }
         
        memset(cOrigData, 0, sizeof(cOrigData));
        BitToChar(cOrigChar, cOrigData);
}
 
void XOREncryptLeft(char cLeftChar[], char cRightChar[], int iIndex)
{
        char cExtendChar[48] = { 0 };
        int i = 0, moveNum = 0, col = 0, row = 0, j = 0, k = 0, l = 0;
        char cLeftKey[28] = { 0 }, cRightKey[28] = { 0 };
        char bEncryptKey[48] = { 0 };
        char bSData[32] = { 0 };
        char cSData = 0;
         
        //进行扩展E置换
        for (i = 0; i < 48; i++)
        {
                cExtendChar[i] = cRightChar[E_Table[i]];
        }
         
        for (i = 0; i < 28; i++)
        {
                cLeftKey[i] = bKey[i];
                cRightKey[i] = bKey[28 + i];
        }
         
        moveNum = RoundLeft[iIndex];
        for (i = 0; i < 28 - moveNum; i++)
        {
                cLeftKey[i] = cLeftKey[i + moveNum];
                cRightKey[i] = cRightKey[i + moveNum];
        }
         
        for (i = 28 - moveNum; i < 28; i++)
        {
                cLeftKey[i] = 0;
                cRightKey[i] = 0;
        }
         
        for (i = 0; i < 28; i++)
        {
                bKey[i] = cLeftKey[i];
                bKey[28 + i] = cRightKey[i];
        }
         
        for (i = 0; i < 48; i++) bEncryptKey[i] = bKey[PC_2[i]];
         
        for (i = 0; i < 48; i++) cExtendChar[i] |= bEncryptKey[i];
         
        for (i = 0; i < 8; i++)
        {
                row = (cExtendChar[i * 8] - '0') * 2 + (cExtendChar[i * 8 + 5] - '0');
                col = (cExtendChar[i * 8 + 1] - '0') * 8 + (cExtendChar[i * 8 + 2] - '0') * 4
                        + (cExtendChar[i * 8 + 3] - '0') * 2 + (cExtendChar[i * 8 + 4] - '0');
                         
                cSData = S[iIndex][row][col];
                if (cSData >= 8)
                {
                        bSData[i * 4] = 1;
                        cSData -= 8;
                }
                 
                if (cSData >= 4)
                {
                        bSData[i * 4 + 1] = 1;
                        cSData -= 4;
                }
                 
                if (cSData >= 2)
                {
                        bSData[i * 4 + 2] = 1;
                        cSData -= 2;
                }
                 
                if (cSData == 1) bSData[i * 4 + 3] = 1;
        }
         
        for (i = 0; i < 32; i++) cLeftChar[i] |= bSData[i];
}
 
void InitBitKey()
{
        int i = 0, j = 0, k = 0;
        char bCpyKey[56] = { 0 };
         
        for (i = 0; i < 7; i++)
        {
                for (j = 0; j < 8; j++)
                {
                        k = 7 - j;
                        bKey[i * 8 + j] = (cKey[i] >> k) & 0x1;
                }
        }
         
        memset(bCpyKey, 0, sizeof(bCpyKey));
        memcpy(bCpyKey, bKey, 56);
        for (i = 0; i < 56; i++)
        {
                bKey[i] = bCpyKey[PC_1[i]];
        }
}

          可以看到最终的输出,程序成功对输入的字符进行DES的加密解密
image.png

DES.rar

113.48 KB, 下载次数: 62, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 4威望 +1 吾爱币 +22 热心值 +4 收起 理由
cimery + 1 + 1 今天实验课要用到DES,用起来很懵!前来学习一下博主的成果~还没理解
笙若 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
andi526 + 1 我很赞同!
苏紫方璇 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

  • · Aarow|主题: 970, 订阅: 305

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| LegendSaber 发表于 2021-10-24 12:53
Eaglecad 发表于 2021-10-24 12:51
感谢分享,要是再讲解下原理啥的更好

哦。。那是因为这种经典的密码算法原理网上真的特别特别多。。再写的话挺多余的。。。。
 楼主| LegendSaber 发表于 2021-10-24 13:18
nanaqilin 发表于 2021-10-24 13:07
我早就不是学生了,我是社会人事,现在做项目都是用openssl

实际项目肯定是调包啊。。。谁能写的比那些人好啊。。。
Eaglecad 发表于 2021-10-24 12:51
nanaqilin 发表于 2021-10-24 12:58
你这个挺厉害的,我都是用openssl来实现加解密
 楼主| LegendSaber 发表于 2021-10-24 13:00
nanaqilin 发表于 2021-10-24 12:58
你这个挺厉害的,我都是用openssl来实现加解密

谁还不是被挂科的恐惧逼了一把。。。

点评

当年被密码学考试支配的恐惧  详情 回复 发表于 2021-10-24 15:34
nanaqilin 发表于 2021-10-24 13:07
LegendSaber 发表于 2021-10-24 13:00
谁还不是被挂科的恐惧逼了一把。。。

我早就不是学生了,我是社会人事,现在做项目都是用openssl
大脑组织残缺 发表于 2021-10-24 13:34
DES,RSA 网络安全课上做过
yacc 发表于 2021-10-24 15:34
LegendSaber 发表于 2021-10-24 13:00
谁还不是被挂科的恐惧逼了一把。。。

当年被密码学考试支配的恐惧
谁的坏叔叔 发表于 2021-10-24 19:39
有易语言的吗
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-4-4 02:16

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表