木落长安rr

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

利用C语言实现DES算法,分组密码原理过程很简单,但是在写的过程中检查了好久才发现错误原因,主要有两点:

1.在加密过程16轮迭代过程中,最后一轮迭代运算后的结果并没有进行交换,即C=IP-1(R16,L16),这样做的目的是为了加密解密使用同一个算法

2.在S盒的过程中,移位后应该加括号,否则+的优先级高于<<,会出错,下面是算法源码:

  1 #include "des.h"
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 
  5 const unsigned char IP_table[64] = {
  6 58, 50, 42, 34, 26, 18, 10, 2,
  7 60, 52, 44, 36, 28, 20, 12, 4,
  8 62, 54, 46, 38, 30, 22, 14, 6,
  9 64, 56, 48, 40, 32, 24, 16, 8,
 10 57, 49, 41, 33, 25, 17, 9, 1,
 11 59, 51, 43, 35, 27, 19, 11, 3,
 12 61, 53, 45, 37, 29, 21, 13, 5,
 13 63, 55, 47, 39, 31, 23, 15, 7
 14 };
 15 
 16 const unsigned char IPR_table[64] = {
 17 40, 8, 48, 16, 56, 24, 64, 32,
 18 39, 7, 47, 15, 55, 23, 63, 31,
 19 38, 6, 46, 14, 54, 22, 62, 30,
 20 37, 5, 45, 13, 53, 21, 61, 29,
 21 36, 4, 44, 12, 52, 20, 60, 28,
 22 35, 3, 43, 11, 51, 19, 59, 27,
 23 34, 2, 42, 10, 50, 18, 58, 26,
 24 33, 1, 41, 9, 49, 17, 57, 25
 25 };
 26 
 27 const unsigned char E_table[48] = {
 28 32, 1, 2, 3, 4, 5,
 29 4, 5, 6, 7, 8, 9,
 30 8, 9, 10, 11, 12, 13,
 31 12, 13, 14, 15, 16, 17,
 32 16, 17, 18, 19, 20, 21,
 33 20, 21, 22, 23, 24, 25,
 34 24, 25, 26, 27, 28, 29,
 35 28, 29, 30, 31, 32, 1
 36 };
 37 
 38 const unsigned char P_table[32] = {
 39 16, 7, 20, 21, 29, 12, 28, 17,
 40 1, 15, 23, 26, 5, 18, 31, 10,
 41 2, 8, 24, 14, 32, 27, 3, 9,
 42 19, 13, 30, 6, 22, 11, 4, 25
 43 };
 44 
 45 const unsigned char PC1_table[56] = {
 46 57, 49, 41, 33, 25, 17, 9,
 47 1, 58, 50, 42, 34, 26, 18,
 48 10, 2, 59, 51, 43, 35, 27,
 49 19, 11, 3, 60, 52, 44, 36,
 50 63, 55, 47, 39, 31, 23, 15,
 51 7, 62, 54, 46, 38, 30, 22,
 52 14, 6, 61, 53, 45, 37, 29,
 53 21, 13, 5, 28, 20, 12, 4
 54 };
 55 
 56 const unsigned char LOOP_table[16] = {
 57 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
 58 };
 59 
 60 const unsigned char PC2_table[48] = {
 61 14, 17, 11, 24, 1, 5,
 62 3, 28, 15, 6, 21, 10,
 63 23, 19, 12, 4, 26, 8,
 64 16, 7, 27, 20, 13, 2,
 65 41, 52, 31, 37, 47, 55,
 66 30, 40, 51, 45, 33, 48,
 67 44, 49, 39, 56, 34, 53,
 68 46, 42, 50, 36, 29, 32
 69 };
 70 
 71 const unsigned char sbox[8][4][16] = {
 72 // S1 
 73 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
 74 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
 75 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
 76 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
 77 //S2
 78 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
 79 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
 80 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
 81 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
 82 //S3
 83 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
 84 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
 85 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
 86 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
 87 //S4
 88 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
 89 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
 90 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
 91 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
 92 //S5
 93 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
 94 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
 95 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
 96 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
 97 //S6
 98 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
 99 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
100 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
101 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
102 //S7
103 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
104 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
105 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
106 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
107 //S8
108 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
109 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
110 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
111 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
112 };
113 
114 void ByteToBit(unsigned char* out, const unsigned char* in, const int bits){
115 for(int i=0;i<bits;i++)
116 out[i]=(in[i/8]>>(7-i%8))&1;
117 }
118 
119 void BitToByte(unsigned char* out, const unsigned char* in, const int bits){
120 memset(out, 0, (bits + 7) / 8);
121 for(int i=0;i<bits;i++)
122 out[i/8]|=in[i]<<(7-i%8);
123 }
124 
125 void Transform(unsigned char* out,const unsigned char* in, const unsigned char* table, const int len){
126 unsigned char tmp[64] = {0};
127 for (int i = 0; i < len; i++)
128 tmp[i] = in[table[i] - 1];
129 memcpy(out, tmp, len);
130 }
131 
132 void RotateL(unsigned char* in, const int len, int loop){
133 static unsigned char tmp[64];
134 memcpy(tmp, in, len);
135 memcpy(in, in + loop, len - loop);
136 memcpy(in + len - loop, tmp, loop);
137 }
138 
139 static unsigned char subKey[16][48] = { 0 };
140 void setKey(const unsigned char* in){
141 char key[64] = { 0 };
142 ByteToBit(key, in, 64);
143 char temp[56]={0};
144 Transform(temp, key, PC1_table, 56);
145 for(int i=0;i<16;i++){
146 RotateL(temp, 28, LOOP_table[i]);
147 RotateL(temp + 28, 28, LOOP_table[i]);
148 Transform(subKey[i], temp, PC2_table, 48);
149 }
150 }
151 
152 void xor(unsigned char* in1,const unsigned char* in2,int len){
153 for(int i=0;i<len;i++)
154 in1[i]^=in2[i];
155 }
156 
157 void sbox_exchange(unsigned char* out,const unsigned char* in){
158 char row, column;
159 for (int i = 0; i < 8; i++){
160 char num = 0;
161 row = (in[6 * i]<<1)+ in[6 * i + 5];
162 column = (in[6 * i + 1] << 3) + (in[6 * i + 2] << 2) + (in[6 * i + 3] << 1) + in[6 * i + 4];
163 num = sbox[i][row][column];
164 for (int j = 0; j < 4; j++)
165 {
166 out[4 * i + j] = (num >> (3 - j)) & 1;
167 }
168 }
169 }
170 
171 void F_func(unsigned char* out,const unsigned char* in,unsigned char* subKey){
172 unsigned char temp[48]={0};
173 unsigned char res[32]={0};
174 Transform(temp, in, E_table, 48);
175 xor(temp,subKey,48);
176 sbox_exchange(res,temp);
177 Transform(out, res, P_table, 32);
178 }
179 
180 void encryptDES(unsigned char* out,const unsigned char* in, const unsigned char* key){
181     unsigned char input[64] = { 0 };
182     unsigned char output[64] = { 0 };
183     unsigned char tmp[64] = { 0 };
184     ByteToBit(input, in, 64);
185     Transform(tmp, input, IP_table, 64);
186     char* Li = &tmp[0], *Ri = &tmp[32];
187     setKey(key);
188     for(int i=0;i<16;i++){
189         char temp[32]={0};
190         memcpy(temp,Ri,32);
191         F_func(Ri, Ri,subKey[i]);
192         xor(Ri, Li, 32);
193         memcpy(Li,temp,32);
194     }
195     RotateL(tmp, 64, 32);//the input is LR,output is RL
196     Transform(output, tmp, IPR_table, 64);
197     BitToByte(out, output,64);
198 }
199 
200 void decryptDES(unsigned char* out,const unsigned char* in, const unsigned char* key){
201     unsigned char input[64] = { 0 };
202     unsigned char output[64] = { 0 };
203     unsigned char tmp[64] = { 0 };
204     ByteToBit(input, in, 64);
205     Transform(tmp, input, IP_table, 64);
206     char* Li = &tmp[0], *Ri = &tmp[32];
207     setKey(key);
208     RotateL(tmp, 64, 32);
209     for (int i = 0; i < 16; i++){
210         char temp[32] = { 0 };
211         memcpy(temp, Li, 32);
212         F_func(Li, Li,subKey[15 - i]);
213         xor(Li, Ri, 32);
214         memcpy(Ri, temp, 32);
215     }
216     Transform(output, tmp, IPR_table, 64);
217     BitToByte(out, output, 64);
218 }

 

posted on 2020-07-30 14:00  木落长安rr  阅读(851)  评论(0编辑  收藏  举报