空军

skyiv studio

导航

一个Delphi写的DES算法, 翻译成C#

其实.NET Framework已经提供实现DES算法的类: System.Security.Cryptography.DESCryptoServiceProvider。之所以要把一个Delphi写的DES算法翻译成C#,是因为网友espnstar想用Delphi加密,C#解密,详见CSDN贴子: http://topic.csdn.net/t/20050726/18/4169690.html

  1// Des.cs - 一个Delphi写的DES算法, 翻译成C#
  2// Wed 2005.09.14
  3
  4// public byte[] EncryBytes (byte[] inData, byte[] keyByte);
  5// public byte[] DecryBytes (byte[] inData, byte[] keyByte);
  6// public string EncryStr   (string Str,    string Key    );
  7// public string DecryStr   (string Str,    string Key    );
  8// public string EncryStrHex(string Str,    string Key    );
  9// public string DecryStrHex(string StrHex, string Key    );
 10
 11namespace Skyiv
 12{
 13  using System;
 14  using System.Text;
 15
 16  enum TDesMode { dmEncry, dmDecry };
 17
 18  class Des
 19  {
 20    static readonly byte [] BitIP =
 21    {
 22      574941332517,  9,  1,
 23      59514335271911,  3,
 24      61534537292113,  5,
 25      63554739312315,  7,
 26      564840322416,  8,  0,
 27      58504234261810,  2,
 28      60524436282012,  4,
 29      62544638302214,  6
 30    }
;
 31
 32    static readonly byte [] BitCP =
 33    {
 34      39,  7471555236331,
 35      38,  6461454226230,
 36      37,  5451353216129,
 37      36,  4441252206028,
 38      35,  3431151195927,
 39      34,  2421050185826,
 40      33,  141,  949175725,
 41      32,  040,  848165624
 42    }
;
 43
 44    static readonly int  [] BitExp =
 45    {
 46      3101234345678789,10,
 47      11,12,11,12,13,14,15,16,15,16,17,18,19,20,19,20,
 48      21,22,23,24,23,24,25,26,27,28,27,28,29,30,310
 49    }
;
 50
 51    static readonly byte [] BitPM =
 52    {
 53      156,19,20,28,11,27,160,14,22,254,17,309,
 54       17,23,13,31,2628,18,12,295,21,103,24
 55    }
;
 56
 57    static readonly byte [,] sBox =
 58    {
 59      {
 60        14,  413,  1,  21511,  8,  310,  612,  5,  9,  0,  7,
 61         015,  7,  414,  213,  110,  61211,  9,  5,  3,  8,
 62         4,  114,  813,  6,  2111512,  9,  7,  310,  5,  0,
 63        1512,  8,  2,  4,  9,  1,  7,  511,  31410,  0,  613
 64      }
,
 65      {
 66        15,  1,  814,  611,  3,  4,  9,  7,  21312,  0,  510,
 67         313,  4,  715,  2,  81412,  0,  110,  6,  911,  5,
 68         014,  71110,  413,  1,  5,  812,  6,  9,  3,  215,
 69        13,  810,  1,  315,  4,  211,  6,  712,  0,  514,  9
 70      }
,
 71      {
 72        10,  0,  914,  6,  315,  5,  11312,  711,  4,  2,  8,
 73        13,  7,  0,  9,  3,  4,  610,  2,  8,  514121115,  1,
 74        13,  6,  4,  9,  815,  3,  011,  1,  212,  51014,  7,
 75         11013,  0,  6,  9,  8,  7,  41514,  311,  5,  212
 76      }
,
 77      {
 78         71314,  3,  0,  6,  910,  1,  2,  8,  51112,  415,
 79        13,  811,  5,  615,  0,  3,  4,  7,  212,  11014,  9,
 80        10,  6,  9,  01211,  71315,  1,  314,  5,  2,  8,  4,
 81         315,  0,  610,  113,  8,  9,  4,  51112,  7,  214
 82      }
,
 83      {
 84         212,  4,  1,  71011,  6,  8,  5,  31513,  014,  9,
 85        1411,  212,  4,  713,  1,  5,  01510,  3,  9,  8,  6,
 86         4,  2,  1111013,  7,  815,  912,  5,  6,  3,  014,
 87        11,  812,  7,  114,  213,  615,  0,  910,  4,  5,  3
 88      }
,
 89      {
 90        12,  11015,  9,  2,  6,  8,  013,  3,  414,  7,  511,
 91        1015,  4,  2,  712,  9,  5,  6,  11314,  011,  3,  8,
 92         91415,  5,  2,  812,  3,  7,  0,  410,  11311,  6,
 93         4,  3,  212,  9,  515101114,  1,  7,  6,  0,  813
 94      }
,
 95      {
 96         411,  21415,  0,  813,  312,  9,  7,  510,  6,  1,
 97        13,  011,  7,  4,  9,  11014,  3,  512,  215,  8,  6,
 98         1,  4111312,  3,  7141015,  6,  8,  0,  5,  9,  2,
 99         61113,  8,  1,  410,  7,  9,  5,  01514,  2,  312
100      }
,
101      {
102        13,  2,  8,  4,  61511,  110,  9,  314,  5,  012,  7,
103         11513,  810,  3,  7,  412,  5,  611,  014,  9,  2,
104         711,  4,  1,  91214,  2,  0,  6101315,  3,  5,  8,
105         2,  114,  7,  410,  8131512,  9,  0,  3,  5,  611
106      }

107    }
;
108
109    static readonly byte [] BitPMC1 =
110    {
111      564840322416,  8,
112       0574941332517,
113       9,  15850423426,
114      1810,  259514335,
115      62544638302214,
116       6615345372921,
117      13,  56052443628,
118      2012,  4271911,  3
119    }
;
120
121    static readonly byte [] BitPMC2 =
122    {
123      13161023,  0,  4,
124       22714,  520,  9,
125      221811,  325,  7,
126      15,  6261912,  1,
127      405130364654,
128      293950443247,
129      434838553352,
130      454149352831
131    }
;
132
133    byte [][] SubKey;
134
135    public Des()
136    {
137      SubKey = new byte [16][];
138      for (int i = 0; i < SubKey.Length; i++)
139      {
140        SubKey[i] = new byte [6];
141      }

142    }

143
144    void initPermutation(byte [] inData)
145    {
146      byte [] newData = new byte [8];
147      for (int i = 0; i < 64; i++)
148      {
149        if ((inData[BitIP[i] >> 3& (1 << (7 - (BitIP[i] & 0x07)))) != 0)
150        {
151          newData[i >> 3|= (byte)(1 << (7 - (i & 0x07)));
152        }

153      }

154      Array.Copy(newData, inData, 8);
155    }

156
157    void conversePermutation(byte [] inData)
158    {
159      byte [] newData = new byte [8];
160      for (int i = 0; i < 64; i++)
161      {
162        if ((inData[BitCP[i] >> 3& (1 << (7 - (BitCP[i] & 0x07)))) != 0)
163        {
164          newData[i >> 3|= (byte)(1 << (7 - (i & 0x07)));
165        }

166      }

167      Array.Copy(newData, inData, 8);
168    }

169
170    void expand(byte [] inData, byte [] outData)
171    {
172      Array.Clear(outData, 06);
173      for (int i = 0; i < 48; i++)
174      {
175        if ((inData[BitExp[i] >> 3& (1 << (7 - (BitExp[i] & 0x07)))) != 0)
176        {
177          outData[i >> 3|= (byte)(1 << (7 - (i & 0x07)));
178        }

179      }

180    }

181
182    void permutation(byte [] inData)
183    {
184      byte [] newData = new byte [4];
185      for (int i = 0; i < 32; i++)
186      {
187        if ((inData[BitPM[i] >> 3& (1 << (7 - (BitPM[i] & 0x07)))) != 0)
188        {
189          newData[i >> 3|= (byte)(1 << (7 - (i & 0x07)));
190        }

191      }

192      Array.Copy(newData, inData, 4);
193    }

194
195    byte si(byte s, byte inByte)
196    {
197      int c = (inByte & 0x20| ((inByte & 0x1e>> 1| ((inByte & 0x01<< 4);
198      return (byte)(sBox[s,c] & 0x0f);
199    }

200
201    void permutationChoose1(byte [] inData, byte [] outData)
202    {
203      Array.Clear(outData, 07);
204      for (int i = 0; i < 56; i++)
205      {
206        if ((inData[BitPMC1[i] >> 3& (1 << (7 - (BitPMC1[i] & 0x07)))) != 0)
207        {
208          outData[i >> 3|= (byte)(1 << (7 - (i & 0x07)));
209        }

210      }

211    }

212
213    void permutationChoose2(byte [] inData, byte [] outData)
214    {
215      Array.Clear(outData, 06);
216      for (int i = 0; i < 48; i++)
217      {
218        if ((inData[BitPMC2[i] >> 3& (1 << (7 - (BitPMC2[i] & 0x07)))) != 0)
219        {
220          outData[i >> 3|= (byte)(1 << (7 - (i & 0x07)));
221        }

222      }

223    }

224
225    void cycleMove(byte [] inData, byte bitMove)
226    {
227      for (int i = 0; i < bitMove; i++)
228      {
229        inData[0= (byte)((inData[0<< 1| (inData[1>> 7));
230        inData[1= (byte)((inData[1<< 1| (inData[2>> 7));
231        inData[2= (byte)((inData[2<< 1| (inData[3>> 7));
232        inData[3= (byte)((inData[3<< 1| ((inData[0& 0x10>> 4));
233        inData[0= (byte)(inData[0& 0x0f);
234      }

235    }

236
237    static readonly byte [] bitDisplace = 1,1,2,22,2,2,21,2,2,22,2,2,1 };
238
239    void makeKey(byte [] inKey, byte [][] outKey)
240    {
241      byte [] outData56 = new byte [7];
242      byte [] key28l    = new byte [4];
243      byte [] key28r    = new byte [4];
244      byte [] key56o    = new byte [7];
245
246      permutationChoose1(inKey, outData56);
247      key28l[0= (byte)(outData56[0>> 4);
248      key28l[1= (byte)((outData56[0<< 4| (outData56[1>> 4));
249      key28l[2= (byte)((outData56[1<< 4| (outData56[2>> 4));
250      key28l[3= (byte)((outData56[2<< 4| (outData56[3>> 4));
251      key28r[0= (byte)(outData56[3& 0x0f);
252      key28r[1= (byte)(outData56[4]);
253      key28r[2= (byte)(outData56[5]);
254      key28r[3= (byte)(outData56[6]);
255
256      for (int i = 0; i < 16; i++)
257      {
258        cycleMove(key28l, bitDisplace[i]);
259        cycleMove(key28r, bitDisplace[i]);
260        key56o[0= (byte)((key28l[0<< 4| (key28l[1>> 4));
261        key56o[1= (byte)((key28l[1<< 4| (key28l[2>> 4));
262        key56o[2= (byte)((key28l[2<< 4| (key28l[3>> 4));
263        key56o[3= (byte)((key28l[3<< 4| (key28r[0]));
264        key56o[4= (byte)(key28r[1]);
265        key56o[5= (byte)(key28r[2]);
266        key56o[6= (byte)(key28r[3]);
267        permutationChoose2(key56o, outKey[i]);
268      }
;
269    }

270
271    void encry(byte [] inData, byte [] subKey, byte [] outData)
272    {
273      byte [] outBuf = new byte [6];
274      byte [] buf    = new byte [8];
275
276      expand(inData, outBuf);
277      for (int i = 0; i < 6; i++) outBuf[i] = (byte)(outBuf[i] ^ subKey[i]);
278                                                            // outBuf  xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
279      buf[0= (byte)(outBuf[0>> 2);                               //xxxxxx -> 2
280      buf[1= (byte)(((outBuf[0& 0x03<< 4| (outBuf[1>> 4)); // 4 <- xx xxxx -> 4
281      buf[2= (byte)(((outBuf[1& 0x0f<< 2| (outBuf[2>> 6)); //        2 <- xxxx xx -> 6
282      buf[3= (byte)(outBuf[2& 0x3f);                             //                    xxxxxx
283      buf[4= (byte)(outBuf[3>> 2);                               //                           xxxxxx
284      buf[5= (byte)(((outBuf[3& 0x03<< 4| (outBuf[4>> 4)); //                                 xx xxxx
285      buf[6= (byte)(((outBuf[4& 0x0f<< 2| (outBuf[5>> 6)); //                                        xxxx xx
286      buf[7= (byte)(outBuf[5& 0x3f);                             //                                               xxxxxx
287      for (int i = 0; i < 8; i++) buf[i] = si((byte)i, buf[i]);
288      for (int i = 0; i < 4; i++) outBuf[i] = (byte)((buf[i*2<< 4| buf[i*2+1]);
289      permutation(outBuf);
290      for (int i = 0; i < 4; i++) outData[i] = outBuf[i];
291    }

292
293    // inData, outData 都为 8 Bytes,否则出错
294    void desData(TDesMode desMode, byte [] inData, byte [] outData)
295    {
296      int  i, j;
297      byte [] temp = new byte [4];
298      byte [] buf  = new byte [4];
299
300      for (i = 0; i < 8; i++) outData[i] = inData[i];
301      initPermutation(outData);
302      if (desMode == TDesMode.dmEncry)
303      {
304        for (i = 0; i < 16; i++)
305        {
306          for (j = 0; j < 4; j++) temp[j] = outData[j];                     //temp = Ln
307          for (j = 0; j < 4; j++) outData[j] = outData[j+4];                //Ln+1 = Rn
308          encry(outData, SubKey[i], buf);                                   //Rn ==Kn==> buf
309          for (j = 0; j < 4; j++) outData[j+4= (byte)(temp[j] ^ buf[j]);  //Rn+1 = Ln^buf
310        }
;
311        for (j = 0; j < 4; j++) temp[j] = outData[j+4];
312        for (j = 0; j < 4; j++) outData[j+4= outData[j];
313        for (j = 0; j < 4; j++) outData[j] = temp[j];
314      }

315      else if (desMode == TDesMode.dmDecry)
316      {
317        for (i = 15; i >= 0; i--)
318        {
319          for (j = 0; j < 4; j++) temp[j] = outData[j];
320          for (j = 0; j < 4; j++) outData[j] = outData[j+4];
321          encry(outData, SubKey[i], buf);
322          for (j = 0; j < 4; j++) outData[j+4= (byte)(temp[j] ^ buf[j]);
323        }
;
324        for (j = 0; j < 4; j++) temp[j] = outData[j+4];
325        for (j = 0; j < 4; j++) outData[j+4= outData[j];
326        for (j = 0; j < 4; j++) outData[j] = temp[j];
327      }
;
328      conversePermutation(outData);
329    }

330
331    byte [] Redim(byte [] arr, int newSize)
332    {
333      if (newSize == arr.Length) return arr;
334      byte [] newArr = new byte [newSize];
335      Array.Copy(arr, 0, newArr, 0, Math.Min(arr.Length, newSize));
336      return newArr;
337    }

338
339    //////////////////////////////////////////////////////////////
340
341    public byte [] EncryBytes(byte [] inData, byte [] keyByte)
342    {
343      byte [] tmpByte = new byte [8];
344      byte [] outByte = new byte [8];
345
346      if ((inData.Length > 0&& (inData[inData.Length-1== 0))
347      {
348        throw new ArgumentException("The last byte is 0.""inData");
349      }

350      if (inData.Length % 8 != 0) inData = Redim(inData, (inData.Length+7)/8*8);
351      if (keyByte.Length != 8) keyByte = Redim(keyByte, 8);
352      makeKey(keyByte, SubKey);
353
354      byte [] outData = new byte [inData.Length];
355      for (int i = 0; i < inData.Length / 8; i++)
356      {
357        for (int j = 0; j < 8; j++)
358        {
359          tmpByte[j] = inData[i * 8 + j];
360        }

361        desData(TDesMode.dmEncry, tmpByte, outByte);
362        for (int j = 0; j < 8; j++)
363        {
364          outData[i * 8 + j] = outByte[j];
365        }

366      }
;
367
368      return outData;
369    }

370
371    public byte [] DecryBytes(byte [] inData, byte [] keyByte)
372    {
373      byte [] tmpByte = new byte [8];
374      byte [] outByte = new byte [8];
375
376      if (keyByte.Length != 8) keyByte = Redim(keyByte, 8);
377      makeKey(keyByte, SubKey);
378
379      byte [] outData = new byte [(inData.Length+7)/8*8];
380      for (int i = 0; i < inData.Length / 8; i++)
381      {
382        for (int j = 0; j < 8; j++)
383        {
384          tmpByte[j] = inData[i * 8 + j];
385        }

386        desData(TDesMode.dmDecry, tmpByte, outByte);
387        for (int j = 0; j < 8; j++)
388        {
389          outData[i * 8 + j] = outByte[j];
390        }

391      }
;
392
393      int n = outData.Length - 1;
394      while (n >= 0 && outData[n] == 0--n;
395      return Redim(outData, n+1);
396    }

397
398    public string EncryStr(string Str, string Key)
399    {
400      byte [] inData  = Encoding.UTF8.GetBytes(Str);
401      byte [] keyByte = Encoding.UTF8.GetBytes(Key);
402      byte [] tmpByte = EncryBytes(inData, keyByte);
403      StringBuilder tmpStr = new StringBuilder();
404      foreach (byte b in tmpByte)
405      {
406        tmpStr.Append((char)b);
407      }

408      return tmpStr.ToString();
409    }

410
411    public string DecryStr(string Str, string Key)
412    {
413      byte [] inData  = new byte [Str.Length];
414      for (int i = 0; i < Str.Length; i++)
415      {
416        inData[i] = (byte)Str[i];
417      }

418      byte [] keyByte = Encoding.UTF8.GetBytes(Key);
419      byte [] tmpByte = DecryBytes(inData, keyByte);
420      return Encoding.UTF8.GetString(tmpByte);
421    }

422
423    public string EncryStrHex(string Str, string Key)
424    {
425      byte [] inData  = Encoding.UTF8.GetBytes(Str);
426      byte [] keyByte = Encoding.UTF8.GetBytes(Key);
427      byte [] tmpByte = EncryBytes(inData, keyByte);
428      StringBuilder tmpStr = new StringBuilder();
429      foreach (byte b in tmpByte)
430      {
431        tmpStr.AppendFormat("{0:X2}", b);
432      }

433      return tmpStr.ToString();
434    }

435
436    public string DecryStrHex(string StrHex, string Key)
437    {
438      if (StrHex.Length % 2 != 0)
439      {
440        throw new ArgumentException("String length must be even.""StrHex");
441      }

442      byte [] inData  = new byte [StrHex.Length / 2];
443      for (int i = 0; i < StrHex.Length; i += 2)
444      {
445        inData[i/2= (byte)(Uri.FromHex(StrHex[i])*16 + Uri.FromHex(StrHex[i+1]));
446      }

447      byte [] keyByte = Encoding.UTF8.GetBytes(Key);
448      byte [] tmpByte = DecryBytes(inData, keyByte);
449      return Encoding.UTF8.GetString(tmpByte);
450    }

451  }
 // End of class Des
452}
   // End of namespace Skyiv
感谢网友espnstar提供Delphi版的源程序:
  1unit Des;
  2
  3interface
  4
  5uses SysUtils;
  6
  7type
  8  TKeyByte = array[0..5] of Byte;
  9  TDesMode = (dmEncry, dmDecry);
 10
 11  function EncryStr(Str, Key: String): String;
 12  function DecryStr(Str, Key: String): String;
 13  function EncryStrHex(Str, Key: String): String;
 14  function DecryStrHex(StrHex, Key: String): String;
 15
 16const
 17  BitIP: array[0..63] of Byte =
 18    (574941332517,  9,  1,
 19     59514335271911,  3,
 20     61534537292113,  5,
 21     63554739312315,  7,
 22     564840322416,  8,  0,
 23     58504234261810,  2,
 24     60524436282012,  4,
 25     62544638302214,  6 );
 26
 27  BitCP: array[0..63] of Byte =
 28    ( 39,  7471555236331,
 29      38,  6461454226230,
 30      37,  5451353216129,
 31      36,  4441252206028,
 32      35,  3431151195927,
 33      34,  2421050185826,
 34      33,  141,  949175725,
 35      32,  040,  848165624 );
 36
 37  BitExp: array[0..47] of Integer =
 38    ( 3101234345678789,10,
 39      11,12,11,12,13,14,15,16,15,16,17,18,19,20,19,20,
 40      21,22,23,24,23,24,25,26,27,28,27,28,29,30,31,0  );
 41
 42  BitPM: array[0..31] of Byte =
 43    ( 156,19,20,28,11,27,160,14,22,254,17,309,
 44       17,23,13,31,2628,18,12,295,21,103,24 );
 45
 46  sBox: array[0..7] of array[0..63] of Byte =
 47    ( ( 14,  413,  1,  21511,  8,  310,  612,  5,  9,  0,  7,
 48         015,  7,  414,  213,  110,  61211,  9,  5,  3,  8,
 49         4,  114,  813,  6,  2111512,  9,  7,  310,  5,  0,
 50        1512,  8,  2,  4,  9,  1,  7,  511,  31410,  0,  613 ),
 51
 52      ( 15,  1,  814,  611,  3,  4,  9,  7,  21312,  0,  510,
 53         313,  4,  715,  2,  81412,  0,  110,  6,  911,  5,
 54         014,  71110,  413,  1,  5,  812,  6,  9,  3,  215,
 55        13,  810,  1,  315,  4,  211,  6,  712,  0,  514,  9 ),
 56
 57      ( 10,  0,  914,  6,  315,  5,  11312,  711,  4,  2,  8,
 58        13,  7,  0,  9,  3,  4,  610,  2,  8,  514121115,  1,
 59        13,  6,  4,  9,  815,  3,  011,  1,  212,  51014,  7,
 60         11013,  0,  6,  9,  8,  7,  41514,  311,  5,  212 ),
 61
 62      (  71314,  3,  0,  6,  910,  1,  2,  8,  51112,  415,
 63        13,  811,  5,  615,  0,  3,  4,  7,  212,  11014,  9,
 64        10,  6,  9,  01211,  71315,  1,  314,  5,  2,  8,  4,
 65         315,  0,  610,  113,  8,  9,  4,  51112,  7,  214 ),
 66
 67      (  212,  4,  1,  71011,  6,  8,  5,  31513,  014,  9,
 68        1411,  212,  4,  713,  1,  5,  01510,  3,  9,  8,  6,
 69         4,  2,  1111013,  7,  815,  912,  5,  6,  3,  014,
 70        11,  812,  7,  114,  213,  615,  0,  910,  4,  5,  3 ),
 71
 72      ( 12,  11015,  9,  2,  6,  8,  013,  3,  414,  7,  511,
 73        1015,  4,  2,  712,  9,  5,  6,  11314,  011,  3,  8,
 74         91415,  5,  2,  812,  3,  7,  0,  410,  11311,  6,
 75         4,  3,  212,  9,  515101114,  1,  7,  6,  0,  813 ),
 76
 77      (  411,  21415,  0,  813,  312,  9,  7,  510,  6,  1,
 78        13,  011,  7,  4,  9,  11014,  3,  512,  215,  8,  6,
 79         1,  4111312,  3,  7141015,  6,  8,  0,  5,  9,  2,
 80         61113,  8,  1,  410,  7,  9,  5,  01514,  2,  312 ),
 81
 82      ( 13,  2,  8,  4,  61511,  110,  9,  314,  5,  012,  7,
 83         11513,  810,  3,  7,  412,  5,  611,  014,  9,  2,
 84         711,  4,  1,  91214,  2,  0,  6101315,  3,  5,  8,
 85         2,  114,  7,  410,  8131512,  9,  0,  3,  5,  611 ) );
 86
 87  BitPMC1: array[0..55] of Byte =
 88    ( 564840322416,  8,
 89       0574941332517,
 90       9,  15850423426,
 91      1810,  259514335,
 92      62544638302214,
 93       6615345372921,
 94      13,  56052443628,
 95      2012,  4271911,  3 );
 96
 97  BitPMC2: array[0..47] of Byte =
 98    ( 13161023,  0,  4,
 99       22714,  520,  9,
100      221811,  325,  7,
101      15,  6261912,  1,
102      405130364654,
103      293950443247,
104      434838553352,
105      454149352831 );
106
107var
108  subKey: array[0..15] of TKeyByte;
109
110implementation
111
112procedure initPermutation(var inData: array of Byte);
113var
114  newData: array[0..7] of Byte;
115  i: Integer;
116begin
117  FillChar(newData, 80);
118  for i := 0 to 63 do
119    if (inData[BitIP[i] shr 3and (1 shl (7- (BitIP[i] and $07)))) <> 0 then
120      newData[i shr 3] := newData[i shr 3or (1 shl (7-(i and $07)));
121  for i := 0 to 7 do inData[i] := newData[i];
122end;
123
124procedure conversePermutation(var inData: array of Byte);
125var
126  newData: array[0..7] of Byte;
127  i: Integer;
128begin
129  FillChar(newData, 80);
130  for i := 0 to 63 do
131    if (inData[BitCP[i] shr 3and (1 shl (7-(BitCP[i] and $07)))) <> 0 then
132      newData[i shr 3] := newData[i shr 3or (1 shl (7-(i and $07)));
133  for i := 0 to 7 do inData[i] := newData[i];
134end;
135
136procedure expand(inData: array of Byte; var outData: array of Byte);
137var
138  i: Integer;
139begin
140  FillChar(outData, 60);
141  for i := 0 to 47 do
142    if (inData[BitExp[i] shr 3and (1 shl (7-(BitExp[i] and $07)))) <> 0 then
143      outData[i shr 3] := outData[i shr 3or (1 shl (7-(i and $07)));
144end;
145
146procedure permutation(var inData: array of Byte);
147var
148  newData: array[0..3] of Byte;
149  i: Integer;
150begin
151  FillChar(newData, 40);
152  for i := 0 to 31 do
153    if (inData[BitPM[i] shr 3and (1 shl (7-(BitPM[i] and $07)))) <> 0 then
154      newData[i shr 3] := newData[i shr 3or (1 shl (7-(i and $07)));
155  for i := 0 to 3 do inData[i] := newData[i];
156end;
157
158function si(s,inByte: Byte): Byte;
159var
160  c: Byte;
161begin
162  c := (inByte and $20or ((inByte and $1e) shr 1or
163    ((inByte and $01) shl 4);
164  Result := (sBox[s][c] and $0f);
165end;
166
167procedure permutationChoose1(inData: array of Byte;
168  var outData: array of Byte);
169var
170  i: Integer;
171begin
172  FillChar(outData, 70);
173  for i := 0 to 55 do
174    if (inData[BitPMC1[i] shr 3and (1 shl (7-(BitPMC1[i] and $07)))) <> 0 then
175      outData[i shr 3] := outData[i shr 3or (1 shl (7-(i and $07)));
176end;
177
178
179
180
181procedure permutationChoose2(inData: array of Byte;
182  var outData: array of Byte);
183var
184  i: Integer;
185begin
186  FillChar(outData, 60);
187  for i := 0 to 47 do
188    if (inData[BitPMC2[i] shr 3and (1 shl (7-(BitPMC2[i] and $07)))) <> 0 then
189      outData[i shr 3] := outData[i shr 3or (1 shl (7-(i and $07)));
190end;
191
192procedure cycleMove(var inData: array of Byte; bitMove: Byte);
193var
194  i: Integer;
195begin
196  for i := 0 to bitMove - 1 do
197  begin
198    inData[0] := (inData[0] shl 1or (inData[1] shr 7);
199    inData[1] := (inData[1] shl 1or (inData[2] shr 7);
200    inData[2] := (inData[2] shl 1or (inData[3] shr 7);
201    inData[3] := (inData[3] shl 1or ((inData[0and $10) shr 4);
202    inData[0] := (inData[0and $0f);
203  end;
204end;
205
206procedure makeKey(inKey: array of Byte; var outKey: array of TKeyByte);
207const
208  bitDisplace: array[0..15] of Byte =
209    ( 1,1,2,22,2,2,21,2,2,22,2,2,1 );
210var
211  outData56: array[0..6] of Byte;
212  key28l: array[0..3] of Byte;
213  key28r: array[0..3] of Byte;
214  key56o: array[0..6] of Byte;
215  i: Integer;
216begin
217  permutationChoose1(inKey, outData56);
218
219  key28l[0] := outData56[0] shr 4;
220  key28l[1] := (outData56[0] shl 4or (outData56[1] shr 4);
221  key28l[2] := (outData56[1] shl 4or (outData56[2] shr 4);
222  key28l[3] := (outData56[2] shl 4or (outData56[3] shr 4);
223  key28r[0] := outData56[3and $0f;
224  key28r[1] := outData56[4];
225  key28r[2] := outData56[5];
226  key28r[3] := outData56[6];
227
228  for i := 0 to 15 do
229  begin
230    cycleMove(key28l, bitDisplace[i]);
231    cycleMove(key28r, bitDisplace[i]);
232    key56o[0] := (key28l[0] shl 4or (key28l[1] shr 4);
233    key56o[1] := (key28l[1] shl 4or (key28l[2] shr 4);
234    key56o[2] := (key28l[2] shl 4or (key28l[3] shr 4);
235    key56o[3] := (key28l[3] shl 4or (key28r[0]);
236    key56o[4] := key28r[1];
237    key56o[5] := key28r[2];
238    key56o[6] := key28r[3];
239    permutationChoose2(key56o, outKey[i]);
240  end;
241end;
242
243procedure encry(inData, subKey: array of Byte;
244   var outData: array of Byte);
245var
246  outBuf: array[0..5] of Byte;
247  buf: array[0..7] of Byte;
248  i: Integer;
249begin
250  expand(inData, outBuf);
251  for i := 0 to 5 do outBuf[i] := outBuf[i] xor subKey[i];
252                                                // outBuf       xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
253  buf[0] := outBuf[0] shr 2;                                  //xxxxxx -> 2
254  buf[1] := ((outBuf[0and $03) shl 4or (outBuf[1] shr 4); // 4 <- xx xxxx -> 4
255  buf[2] := ((outBuf[1and $0f) shl 2or (outBuf[2] shr 6); //        2 <- xxxx xx -> 6
256  buf[3] := outBuf[2and $3f;                                //                    xxxxxx
257  buf[4] := outBuf[3] shr 2;                                  //                           xxxxxx
258  buf[5] := ((outBuf[3and $03) shl 4or (outBuf[4] shr 4); //                                 xx xxxx
259  buf[6] := ((outBuf[4and $0f) shl 2or (outBuf[5] shr 6); //                                        xxxx xx
260  buf[7] := outBuf[5and $3f;                                //                                               xxxxxx
261  for i := 0 to 7 do buf[i] := si(i, buf[i]);
262  for i := 0 to 3 do outBuf[i] := (buf[i*2] shl 4or buf[i*2+1];
263  permutation(outBuf);
264  for i := 0 to 3 do outData[i] := outBuf[i];
265end;
266
267procedure desData(desMode: TDesMode;
268  inData: array of Byte; var outData: array of Byte);
269// inData, outData 都为8Bytes,否则出错
270var
271  i, j: Integer;
272  temp, buf: array[0..3] of Byte;
273begin
274  for i := 0 to 7 do outData[i] := inData[i];
275  initPermutation(outData);
276  if desMode = dmEncry then
277  begin
278    for i := 0 to 15 do
279    begin
280      for j := 0 to 3 do temp[j] := outData[j];                 //temp = Ln
281      for j := 0 to 3 do outData[j] := outData[j + 4];        //Ln+1 = Rn
282      encry(outData, subKey[i], buf);                           //Rn ==Kn==> buf
283      for j := 0 to 3 do outData[j + 4] := temp[j] xor buf[j];  //Rn+1 = Ln^buf
284    end;
285
286    for j := 0 to 3 do temp[j] := outData[j + 4];
287    for j := 0 to 3 do outData[j + 4] := outData[j];
288    for j := 0 to 3 do outData[j] := temp[j];
289  end
290  else if desMode = dmDecry then
291  begin
292    for i := 15 downto 0 do
293    begin
294      for j := 0 to 3 do temp[j] := outData[j];
295      for j := 0 to 3 do outData[j] := outData[j + 4];
296      encry(outData, subKey[i], buf);
297      for j := 0 to 3 do outData[j + 4] := temp[j] xor buf[j];
298    end;
299    for j := 0 to 3 do temp[j] := outData[j + 4];
300    for j := 0 to 3 do outData[j + 4] := outData[j];
301    for j := 0 to 3 do outData[j] := temp[j];
302  end;
303  conversePermutation(outData);
304end;
305
306//////////////////////////////////////////////////////////////
307
308function EncryStr(Str, Key: String): String;
309var
310  StrByte, OutByte, KeyByte: array[0..7] of Byte;
311  StrResult: String;
312  I, J: Integer;
313begin
314  if (Length(Str> 0and (Ord(Str[Length(Str)]) = 0then
315    raise Exception.Create('Error: the last char is NULL char.');
316  if Length(Key) < 8 then
317    while Length(Key) < 8 do Key := Key + Chr(0);
318  while Length(Strmod 8 <> 0 do Str := Str + Chr(0);
319
320  for J := 0 to 7 do KeyByte[J] := Ord(Key[J + 1]);
321  makeKey(keyByte, subKey);
322
323  StrResult := '';
324
325  for I := 0 to Length(Str) div 8 - 1 do
326  begin
327    for J := 0 to 7 do
328      StrByte[J] := Ord(Str[I * 8 + J + 1]);
329    desData(dmEncry, StrByte, OutByte);
330    for J := 0 to 7 do
331      StrResult := StrResult + Chr(OutByte[J]);
332  end;
333
334  Result := StrResult;
335end;
336
337function DecryStr(Str, Key: String): String;
338var
339  StrByte, OutByte, KeyByte: array[0..7] of Byte;
340  StrResult: String;
341  I, J: Integer;
342begin
343  if Length(Key) < 8 then
344    while Length(Key) < 8 do Key := Key + Chr(0);
345
346  for J := 0 to 7 do KeyByte[J] := Ord(Key[J + 1]);
347  makeKey(keyByte, subKey);
348
349  StrResult := '';
350
351  for I := 0 to Length(Str) div 8 - 1 do
352  begin
353    for J := 0 to 7 do StrByte[J] := Ord(Str[I * 8 + J + 1]);
354    desData(dmDecry, StrByte, OutByte);
355    for J := 0 to 7 do
356      StrResult := StrResult + Chr(OutByte[J]);
357  end;
358  while (Length(StrResult) > 0and
359    (Ord(StrResult[Length(StrResult)]) = 0do
360    Delete(StrResult, Length(StrResult), 1);
361  Result := StrResult;
362end;
363
364///////////////////////////////////////////////////////////
365
366function EncryStrHex(Str, Key: String): String;
367var
368  StrResult, TempResult, Temp: String;
369  I: Integer;
370begin
371  TempResult := EncryStr(Str, Key);
372  StrResult := '';
373  for I := 0 to Length(TempResult) - 1 do
374  begin
375    Temp := Format('%x', [Ord(TempResult[I + 1])]);
376    if Length(Temp) = 1 then Temp := '0' + Temp;
377    StrResult := StrResult + Temp;
378  end;
379  Result := StrResult;
380end;
381
382function DecryStrHex(StrHex, Key: String): String;
383  function HexToInt(HexString): Integer;
384  var
385    I, Res: Integer;
386    ch: Char;
387  begin
388    Res := 0;
389    for I := 0 to Length(Hex- 1 do
390    begin
391      ch := Hex[I + 1];
392      if (ch >= '0') and (ch <= '9') then
393        Res := Res * 16 + Ord(ch) - Ord('0')
394      else if (ch >= 'A') and (ch <= 'F') then
395        Res := Res * 16 + Ord(ch) - Ord('A') + 10
396      else if (ch >= 'a') and (ch <= 'f') then
397        Res := Res * 16 + Ord(ch) - Ord('a') + 10
398      else raise Exception.Create('Error: not a Hex String');
399    end;
400    Result := Res;
401  end;
402
403var
404  Str, Temp: String;
405  I: Integer;
406begin
407  Str := '';
408  for I := 0 to Length(StrHex) div 2 - 1 do
409  begin
410    Temp := Copy(StrHex, I * 2 + 12);
411    Str := Str + Chr(HexToInt(Temp));
412  end;
413  Result := DecryStr(Str, Key);
414end;
415
416end.

posted on 2005-09-19 21:11  空军  阅读(4309)  评论(12编辑  收藏  举报