2014-11-07 2 views
2

Я написал DES на C# с нуля, и я выложу здесь весь код, для меня это кажется правильным, но когда я пытаюсь пример, это не так. Вот мой весь код.DES Шифрование не работает C#

Des Класс:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace DES_Cipher 
{ 
    class DES 
    { 
     string leftSide = ""; 
     string rightSide = ""; 
     string tempLeft = ""; 

     F_Function f = new F_Function(); 
     Key_Scheduler k = new Key_Scheduler(); 

     public string DESEncryption(string input, string Key) 
     { 
      input = String.Join(String.Empty, 
    input.Select(
    c => Convert.ToString(Convert.ToInt32(c.ToString(), 16), 2).PadLeft(4, '0') 
) 
); 
      Key = String.Join(String.Empty, 
    Key.Select(
    c => Convert.ToString(Convert.ToInt32(c.ToString(), 16), 2).PadLeft(4, '0') 
) 
); 
      // input = strtoBin(input); 
      string chunk = ""; 
      string finalPerm = ""; 
      string result = ""; 
      string[] subKeys; 

      //split the string into blocks of 64 bits 
      IEnumerable<string> output = Enumerable.Range(0, input.Length/64) 
    .Select(x => input.Substring(x * 64, 64)); 
      string[] newInput = output.ToArray(); 

      //for each block 
      for (int i = 0; i < newInput.Length; i++) 
      { 
       //Initial Permutation 
       chunk = initalPermutation(newInput[i]); 

       //split the chunk in two halves 32 bit each 
       leftSide = chunk.Substring(0, chunk.Length/2); 
       rightSide = chunk.Substring(chunk.Length/2, chunk.Length/2); 
       subKeys = k.keySched(Key); 

       for (int j = 0; j < 16; j++) 
       { 

        //F Function on the right side 
        tempLeft = leftSide; 
        leftSide = rightSide; 
        rightSide = f.f_function(rightSide, subKeys[j]); 
        rightSide = XOR(tempLeft, rightSide); 

       } 

       finalPerm = rightSide + leftSide; 
       finalPerm = finalPermutation(finalPerm); 
       result = result + finalPerm; 
      } 
      result = BinaryStringToHexString(result); 
      return result; 
     } 

     private string initalPermutation(string block) 
     { 


      char[] tempBlock ={block[57],block[49],block[41],block[33],block[25],block[17],block[9],block[1], 
          block[59],block[51],block[43],block[35],block[27],block[19],block[11],block[3], 
          block[61],block[53],block[45],block[37],block[29],block[21],block[13],block[5], 
          block[63],block[55],block[47],block[39],block[31],block[23],block[15],block[7], 
          block[56],block[48],block[40],block[32],block[24],block[16],block[8],block[0], 
          block[58],block[50],block[42],block[34],block[26],block[18],block[10],block[2], 
          block[60],block[52],block[44],block[36],block[28],block[20],block[12],block[4], 
          block[62],block[54],block[46],block[38],block[30],block[22],block[14],block[6]}; 
      string res = new string(tempBlock); 
      return res; 
     } 

     private string finalPermutation(string block) 
     { 

      char[] tempBlock ={block[39],block[7],block[47],block[15],block[55],block[23],block[63],block[31], 
          block[38],block[6],block[46],block[14],block[54],block[22],block[62],block[30], 
          block[37],block[5],block[45],block[13],block[53],block[21],block[61],block[29], 
          block[36],block[4],block[44],block[12],block[52],block[20],block[60],block[28], 
          block[35],block[3],block[43],block[11],block[51],block[19],block[59],block[27], 
          block[34],block[2],block[42],block[10],block[50],block[18],block[58],block[26], 
          block[33],block[1],block[41],block[9],block[49],block[17],block[57],block[25], 
          block[32],block[0],block[40],block[8],block[48],block[16],block[56],block[24]}; 
      string res = new string(tempBlock); 
      return res; 
     } 

     //convert string to binary function 
     private string strtoBin(string input) 
     { 
      StringBuilder sb = new StringBuilder(); 
      foreach (char L in input) 
      { 
       sb.Append(Convert.ToString(L, 2).PadLeft(8, '0')); 

      } 

      return sb.ToString(); 
     } 

     private string XOR(string expanedArray, string key) 
     { 
      string[] result = new string[key.Length]; 
      string res; 
      char[] a = expanedArray.ToCharArray(); 
      char[] b = key.ToCharArray(); 

      for (int i = 0; i < key.Length; i++) 
      { 
       result[i] = (a[i]^b[i]).ToString(); 

      } 
      res = string.Join("", result); 
      return res; 
     } 
     private static string BinaryStringToHexString(string binary) 
     { 
      StringBuilder result = new StringBuilder(binary.Length/8 + 1); 

      // TODO: check all 1's or 0's... Will throw otherwise 

      int mod4Len = binary.Length % 8; 
      if (mod4Len != 0) 
      { 
       // pad to length multiple of 8 
       binary = binary.PadLeft(((binary.Length/8) + 1) * 8, '0'); 
      } 

      for (int i = 0; i < binary.Length; i += 8) 
      { 
       string eightBits = binary.Substring(i, 8); 
       result.AppendFormat("{0:X2}", Convert.ToByte(eightBits, 2)); 
      } 

      return result.ToString(); 
     } 

} 
} 

Key Класс:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace DES_Cipher 
{ 
    class Key_Scheduler 
    { 
     public static String c0 = ""; 
     public static String d0 = ""; 
     public string[] keySched(string key) 
     { 

       string[] keys = new string[16]; 
       string perm1 = ""; 

        //Permutation Choice - 1 
        perm1 = permuatedchoice1(key); 

        //split the key in two halves 28 bit each 
        c0 = perm1.Substring(0, perm1.Length/2); 
        d0 = perm1.Substring(perm1.Length/2, perm1.Length/2); 

        for (int i = 0; i < 16; i++) 
        { 
         keys[i] = GenerateKeys(c0, d0, i); 

        } 

        return keys; 
      } 

     private string GenerateKeys(string L, string R,int i) 
     { 
      string key; 
      if (i == 0 || i == 1 || i == 8 || i == 15) 
      { 
       c0 = rotateShift(L, 1); 
       d0 = rotateShift(R, 1); 

       key = L + R; 
       key = permuatedchoice2(key); 
       return key; 
      } 

      else 
      { 
       c0 = rotateShift(L, 2); 
       d0 = rotateShift(R, 2); 

       key = L + R; 
       key = permuatedchoice2(key); 
       return key; 
      } 


     } 

     private string rotateShift(string key, int shift) 
     { 
      string res=""; 
      string[] result = new string[key.Length]; 
      char[] a = key.ToCharArray(); 
      int index = 0; 
      for (int i = shift; index < a.Length; i++) 
      { 
       result[index++] = a[i % a.Length].ToString(); 
      } 
      res = string.Join("", result); 
      return res; 
     } 
     private string permuatedchoice1(string key) 
     { 
      string res; 
      char[] tempArr ={key[56],key[48],key[40],key[32],key[24],key[16],key[8],key[0], 
          key[57],key[49],key[41],key[33],key[25],key[17],key[9],key[1], 
          key[58],key[50],key[42],key[34],key[26],key[18],key[10],key[2], 
          key[59],key[51],key[43],key[35],key[62],key[54],key[46],key[38], 
          key[30],key[22],key[14],key[6],key[61],key[53],key[45],key[37], 
          key[29],key[21],key[13],key[5],key[60],key[52],key[44],key[36], 
          key[28],key[20],key[12],key[4],key[27],key[19],key[11],key[3]}; 

      res = new string(tempArr); 
      return res; 
     } 

     private string permuatedchoice2(string key) 
     { 
      string res; 
      char[] tempArr ={key[13],key[16],key[10],key[23],key[0],key[4],key[2],key[27], 
          key[14],key[5],key[20],key[9],key[22],key[18],key[11],key[3], 
          key[25],key[7],key[15],key[6],key[26],key[19],key[12],key[1], 
          key[40],key[51],key[30],key[36],key[46],key[54],key[29],key[39], 
          key[50],key[44],key[32],key[47],key[43],key[48],key[38],key[55], 
          key[33],key[52],key[45],key[41],key[49],key[35],key[28],key[31]}; 

      res = new string(tempArr); 
      return res; 
     } 

    } 
} 

И, наконец, F Функция Класс:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace DES_Cipher 
{ 
    class F_Function 
    { 
     #region SBoxes definition 
     int[,] s1Box = {{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}}; 

     int[,] s2Box = {{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}}; 

     int[,] s3Box = {{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}}; 

     int[,] s4Box = {{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}}; 

     int[,] s5Box = {{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}}; 

     int[,] s6Box = {{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}}; 

     int[,] s7Box = {{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}}; 

     int[,] s8Box = {{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}}; 
     #endregion 
     int[] expanstionArr = new int[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, 1 }; 

     int[] permutationMatrix = new int[32] { 15, 6, 19, 20, 28, 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 }; 

     Key_Scheduler key = new Key_Scheduler(); 
     public string f_function(string input, string mainKey) 
     { 
      string res, exp, xor, sboxsub, perm; 
      exp = expansion(input); 
      //subKey =key.keySched(mainKey); 
      int a = mainKey.Length - exp.Length; 
      xor=XORwithKey(exp,mainKey); 
      sboxsub = SBoxSubstitution(xor); 
      perm = permutation(sboxsub); 
      res = perm; 
      return res; 
     } 
     private string expansion (string rightSide) 
     { 
      char[] arr = new char[48]; 
      int len = rightSide.Length; 

      for (int i = 0; i < arr.Length; i++) 
      { 
       arr[i] = rightSide[expanstionArr[i]]; 

      } 
      string res = new string(arr); 
      return res; 
     } 
     private string XORwithKey(string expanedArray,string key) 
     { 
      string[] result = new string[key.Length]; 
      string res; 
      char[] a = expanedArray.ToCharArray(); 
      char[] b = key.ToCharArray(); 

      for (int i = 0; i < key.Length; i++) 
      { 
       result[i] = (a[i]^b[i]).ToString(); 

      } 
      res = string.Join("", result); 
      return res; 
     } 

     private string SBoxSubstitution(string input) 
     { 
      string res=""; 
      string r; 
      int row, col, s1, s2, s3, s4, s5, s6, s7, s8; 
      string c; 
      char[] temp; 
      IEnumerable<string> output = Enumerable.Range(0, input.Length/6) 
       .Select(x => input.Substring(x * 6, 6)); 
      string[] newInput = output.ToArray(); 

      for (int i = 0; i < newInput.Length; i++) 
      { 
       temp = newInput[i].ToCharArray(); 
       r = temp[0].ToString()+temp[5].ToString(); 
       row = Convert.ToInt32(r,2); 
       c = temp[1].ToString() + temp[2].ToString() + temp[3].ToString() + temp[4].ToString(); 
       col = Convert.ToInt32(c,2); 
       if (i == 0) 
       { 
        s1 = SBoxSearch(row, col, s1Box); 
        res += s1.ToString(); 
       } 
       else if (i == 1) 
       { 
        s2 = SBoxSearch(row, col, s2Box); 
        res += s2.ToString(); 
       } 
       else if (i == 2) 
       { 
        s3 = SBoxSearch(row, col, s3Box); 
        res += s3.ToString(); 
       } 
       else if (i == 3) 
       { 
        s4 = SBoxSearch(row, col, s4Box); 
        res += s4.ToString(); 
       } 
       else if (i == 4) 
       { 
        s5 = SBoxSearch(row, col, s5Box); 
        res += s5.ToString(); 
       } 
       else if (i == 5) 
       { 
        s6 = SBoxSearch(row, col, s6Box); 
        res += s6.ToString(); 
       } 
       else if (i == 6) 
       { 
        s7 = SBoxSearch(row, col, s7Box); 
        res += s7.ToString(); 
       } 
       else 
       { 
        s8 = SBoxSearch(row, col, s8Box); 
        res += s8.ToString(); 
       } 
      } 

      res = strtoBin(res); 
      return res; 
     } 

     private string permutation(string input) 
     { 
      char[] arr = new char[32]; 

      for (int i = 0; i < arr.Length; i++) 
      { 
       arr[i] = input[permutationMatrix[i]]; 

      } 
      string res = new string(arr); 

      return res; 
     } 

     private int SBoxSearch(int row, int col, int[,] sBox) 
     { 
      int res=0; 
      for (int i = 0; i < 4; i++) 
      { 
       if (i == row) 
       { 
        for (int j = 0; j < 16; j++) 
        { 
         if (j == col) 
         { 
          res = sBox[i, j]; 
          break; 
         } 
         else continue; 
        } 
        break; 
       } 
       else continue; 
      } 
      return res; 
     } 

     private string strtoBin(string input) 
     { 
      StringBuilder sb = new StringBuilder(); 
      foreach (char L in input) 
      { 
       sb.Append(Convert.ToString(L, 2).PadLeft(8, '0')); 

      } 

      return sb.ToString(); 
     } 


    } 
} 

Когда я проверяю его, кстати все входы в гексагоне, мой ввод: 02468aceeca86420

Б Ключ:

0f1571c947d9e859

выход шифрования должен быть:

da02ce3a89ecac3b

Но я получаю этот выход вместо:

019945B853663D50

я дважды проверил все, и я действительно не знаю, что я сделал не так здесь ... Па rdon меня за грязный код, но он был написан менее чем за один день:/

Спасибо за любой кончик

+0

Любой помощи от кого ?! – WT86

+0

Какова ваша ссылка для сравнения, реализация алгоритма, которую вы считаете правильным? –

+0

@ andrei.ciprian Я использовал это как ссылку http://euro.ecom.cmu.edu/resources/elibrary/epay/DES.pdf – WT86

ответ

1

Проверяющий вектор шифрования (0F1571C947D9E859 02468ACEECA86420 DA02CE3A89ECAC3B) действителен, я проверял стандартную реализацию.

Способ устранения новой реализации DES заключается в сопоставлении округлых значений с известной реализацией, например, с использованием DES Calculator, который производит округлые значения. Вы также можете скопировать известную хорошую реализацию и изменить ее для вывода круглых значений. Это также означает получение одинаковых значений для вашей реализации в каждом раунде.

Ошибка будет отображаться в вашей реализации одной или нескольких перестановок, расписания клавиш или направления сдвига или синтаксиса или семантики языка программирования.

Проще сравнивать бинарные результаты, когда вы имеете дело со строками 1 и 0.

Там также Javascript реализация DES найти на Google Code: JS-DES.html, и если вы хотите, отсутствующие изображения в нижней части страницы, они могут быть найдены на JS-DES_fichiers. Сохраните изображения в подкаталоге JS-DES_fichiers.

Это то, что она производит для

Ключ: 0F1571C947D9E859
Вход: 02468ACEECA86420
(ожидаемый выход: DA02CE3A89ECAC3B)

Input bits: 00000010 01000110 10001010 11001110 11101100 10101000 01100100 00100000 
Key bits: 00001111 00010101 01110001 11001001 01000111 11011001 11101000 01011001 
CD[0]: 0110100 0111111 0001000 1001010 0001000 1000100 1111101 0010110 
CD[1]: 1101000 1111110 0010001 0010100 0010001 0001001 1111010 0101100 
KS[1]: 011110 000011 001111 000011 001000 001101 101001 110000 
CD[2]: 1010001 1111100 0100010 0101001 0100010 0010011 1110100 1011000 
KS[2]: 001010 110001 101001 110100 110010 100100 100011 011000 
CD[3]: 1000111 1110001 0001001 0100110 0001000 1001111 1010010 1100001 
KS[3]: 100011 000111 100011 011000 100000 011101 001100 011101 
CD[4]: 0011111 1000100 0100101 0011010 0100010 0111110 1001011 0000100 
KS[4]: 000101 100110 011101 111000 100100 110001 011010 100000 
CD[5]: 1111110 0010001 0010100 1101000 0001001 1111010 0101100 0010001 
KS[5]: 110011 100101 110100 000001 110110 000000 101100 100101 
CD[6]: 1111000 1000100 1010011 0100011 0100111 1101001 0110000 1000100 
KS[6]: 010010 111010 101101 001101 000100 100110 101010 011100 
CD[7]: 1100010 0010010 1001101 0001111 0011111 0100101 1000010 0010001 
KS[7]: 000010 011111 010010 001011 011100 010011 000110 010001 
CD[8]: 0001000 1001010 0110100 0111111 1111101 0010110 0001000 1000100 
KS[8]: 011100 010000 110111 101010 101000 110010 000000 101011 
CD[9]: 0010001 0010100 1101000 1111110 1111010 0101100 0010001 0001001 
KS[9]: 000100 101001 101010 111000 001100 110100 011111 000011 
CD[10]: 1000100 1010011 0100011 1111000 1101001 0110000 1000100 0100111 
KS[10]: 100111 000011 100001 100110 000111 101000 000100 000011 
CD[11]: 0010010 1001101 0001111 1100010 0100101 1000010 0010001 0011111 
KS[11]: 101000 100110 111001 001100 110001 100110 010101 000100 
CD[12]: 1001010 0110100 0111111 0001000 0010110 0001000 1000100 1111101 
KS[12]: 010010 000111 011100 100100 011010 001010 001111 001000 
CD[13]: 0101001 1010001 1111100 0100010 1011000 0100010 0010011 1110100 
KS[13]: 110000 001001 110101 111001 111100 001101 010000 001011 
CD[14]: 0100110 1000111 1110001 0001001 1100001 0001000 1001111 1010010 
KS[14]: 110001 011110 001001 100011 010011 100001 011000 101010 
CD[15]: 0011010 0011111 1000100 0100101 0000100 0100010 0111110 1001011 
KS[15]: 101000 111101 111110 000010 100111 000111 100101 101000 
CD[16]: 0110100 0111111 0001000 1001010 0001000 1000100 1111101 0010110 
KS[16]: 101001 100001 001000 001011 010011 010100 110000 100101 
L[0]: 01011010 00000000 01011010 00000000 
R[0]: 00111100 11110000 00111100 00001111 
Round 1 
E : 100111 111001 011110 100000 000111 111000 000001 011110 
KS : 011110 000011 001111 000011 001000 001101 101001 110000 
E xor KS: 111001 111010 010001 100011 001111 110101 101000 101110 
Sbox: 1010 0011 0010 1111 0001 0001 1100 0010 
P : 11100000 11010010 01110010 01000101 
L[i]: 00111100 11110000 00111100 00001111 
R[i]: 10111010 11010010 00101000 01000101 
Round 2 
E : 110111 110101 011010 100100 000101 010000 001000 001011 
KS : 001010 110001 101001 110100 110010 100100 100011 011000 
E xor KS: 111101 000100 110011 010000 110111 110100 101011 010011 
Sbox: 0110 1000 1111 0001 1001 0100 0100 0101 
P : 10100101 00011001 10001011 00101100 
L[i]: 10111010 11010010 00101000 01000101 
R[i]: 10011001 11101001 10110111 00100011 
Round 3 
E : 110011 110011 111101 010011 110110 101110 100100 000111 
KS : 100011 000111 100011 011000 100000 011101 001100 011101 
E xor KS: 010000 110100 011110 001011 010110 110011 101000 011010 
Sbox: 0011 1100 1000 1111 1111 1110 1100 0000 
P : 10110001 01111100 00010011 11011011 
L[i]: 10011001 11101001 10110111 00100011 
R[i]: 00001011 10101110 00111011 10011110 
Round 4 
E : 000001 010111 110101 011100 000111 110111 110011 111100 
KS : 000101 100110 011101 111000 100100 110001 011010 100000 
E xor KS: 000100 110001 101000 100100 100011 000110 101001 011100 
Sbox: 1101 1011 1000 1001 1000 1111 0001 1100 
P : 11011011 10101000 11100001 01101010 
L[i]: 00001011 10101110 00111011 10011110 
R[i]: 01000010 01000001 01010110 01001001 
Round 5 
E : 101000 000100 001000 000010 101010 101100 001001 010010 
KS : 110011 100101 110100 000001 110110 000000 101100 100101 
E xor KS: 011011 100001 111100 000011 011100 101100 100101 110111 
Sbox: 0101 1101 1110 1000 1110 1100 1101 0000 
P : 00010011 00011101 11000001 11011111 
L[i]: 01000010 01000001 01010110 01001001 
R[i]: 00011000 10110011 11111010 01000001 
Round 6 
E : 100011 110001 010110 100111 111111 110100 001000 000010 
KS : 010010 111010 101101 001101 000100 100110 101010 011100 
E xor KS: 110001 001011 111011 101010 111011 010010 100010 011110 
Sbox: 0101 0010 0101 1011 0100 1101 0100 0111 
P : 11010100 01010111 10101000 01101010 
L[i]: 00011000 10110011 11111010 01000001 
R[i]: 10010110 00010110 11111110 00100011 
Round 7 
E : 110010 101100 000010 101101 011111 111100 000100 000111 
KS : 000010 011111 010010 001011 011100 010011 000110 010001 
E xor KS: 110000 110011 010000 100110 000011 101111 000010 010110 
Sbox: 1111 0110 0001 0000 1011 1010 1011 1110 
P : 01111111 10100010 10000110 10110011 
L[i]: 10010110 00010110 11111110 00100011 
R[i]: 01100111 00010001 01111100 11110010 
Round 8 
E : 001100 001110 100010 100010 101111 111001 011110 100100 
KS : 011100 010000 110111 101010 101000 110010 000000 101011 
E xor KS: 010000 011110 010101 001000 000111 001011 011110 001111 
Sbox: 0011 1010 0101 0000 1100 1100 0001 0100 
P : 01010111 00001101 00000010 00101010 
L[i]: 01100111 00010001 01111100 11110010 
R[i]: 11000001 00011011 11111100 00001001 
Round 9 
E : 111000 000010 100011 110111 111111 111000 000001 010011 
KS : 000100 101001 101010 111000 001100 110100 011111 000011 
E xor KS: 111100 101011 001001 001111 110011 001100 011110 010000 
Sbox: 0101 1111 0011 0011 1111 0110 0001 1010 
P : 11101111 01101110 11000000 10011110 
L[i]: 11000001 00011011 11111100 00001001 
R[i]: 10001000 01111111 10111100 01101100 
Round 10 
E : 010001 010000 001111 111111 110111 111000 001101 011001 
KS : 100111 000011 100001 100110 000111 101000 000100 000011 
E xor KS: 110110 010011 101110 011001 110000 010000 001001 011010 
Sbox: 0111 0000 0000 0001 1111 0000 0100 0000 
P : 10100001 00010100 10000010 10000010 
L[i]: 10001000 01111111 10111100 01101100 
R[i]: 01100000 00001111 01111110 10001011 
Round 11 
E : 101100 000000 000001 011110 101111 111101 010001 010110 
KS : 101000 100110 111001 001100 110001 100110 010101 000100 
E xor KS: 000100 100110 111000 010010 011110 011011 000100 010010 
Sbox: 1101 1011 0101 0010 1001 1011 0010 1001 
P : 01111101 11101001 11101100 00000010 
L[i]: 01100000 00001111 01111110 10001011 
R[i]: 11110101 10010110 01010000 01101110 
Round 12 
E : 011110 101011 110010 101100 001010 100000 001101 011101 
KS : 010010 000111 011100 100100 011010 001010 001111 001000 
E xor KS: 001100 101100 101110 001000 010000 101010 000010 010101 
Sbox: 1011 1101 0000 0000 1000 1000 1011 0110 
P : 00010011 10001010 01000110 00110011 
L[i]: 11110101 10010110 01010000 01101110 
R[i]: 01110011 10000101 00111000 10111000 
Round 13 
E : 001110 100111 110000 001010 100111 110001 010111 110000 
KS : 110000 001001 110101 111001 111100 001101 010000 001011 
E xor KS: 111110 101110 000101 110011 011011 111100 000111 111011 
Sbox: 0000 0001 0000 0100 1001 1011 0111 0101 
P : 00110011 00110000 01111100 00100000 
L[i]: 01110011 10000101 00111000 10111000 
R[i]: 11000110 10100110 00101100 01001110 
Round 14 
E : 011000 001101 010100 001100 000101 011000 001001 011101 
KS : 110001 011110 001001 100011 010011 100001 011000 101010 
E xor KS: 101001 010011 011101 101111 010110 111001 010001 110111 
Sbox: 0100 0000 1111 1000 1111 0110 1110 0000 
P : 00100101 00110101 10000101 11001101 
L[i]: 11000110 10100110 00101100 01001110 
R[i]: 01010110 10110000 10111101 01110101 
Round 15 
E : 101010 101101 010110 100001 010111 111010 101110 101010 
KS : 101000 111101 111110 000010 100111 000111 100101 101000 
E xor KS: 000010 010000 101000 100011 110000 111101 001011 000010 
Sbox: 0100 1001 1000 1111 1111 1000 1001 0010 
P : 10110011 01001110 11010001 11000001 
L[i]: 01010110 10110000 10111101 01110101 
R[i]: 01110101 11101000 11111101 10001111 
Round 16 
E : 101110 101011 111101 010001 011111 111011 110001 011110 
KS : 101001 100001 001000 001011 010011 010100 110000 100101 
E xor KS: 000111 001010 110101 011010 001100 101111 000001 111011 
Sbox: 0100 1011 1110 1100 1011 1010 1101 0101 
P : 01110011 00111001 11011001 11100101 
L[i]: 01110101 11101000 11111101 10001111 
R[i]: 00100101 10001001 01100100 10010000 
LR[16] 00100101 10001001 01100100 10010000 01110101 11101000 11111101 10001111 
Output 11011010 00000010 11001110 00111010 10001001 11101100 10101100 00111011 

Выходной сообщение da02ce3a89ecac3b

+0

То, что вы сказали, правда. У меня возникли проблемы с генерацией ключей, и я исправил их. Большое вам спасибо за ваши усилия – WT86

+0

Убедитесь, что вы тоже можете расшифровать. – user1155120

+0

По той или иной причине дешифрование не работает, просто изменяя порядок ключей:/ – WT86

0

Это реализация алгоритма DES, как указано в NIST в публикации FIPS PUB 197, доступный на веб-сайте NIST, here. Алгоритм принимает 64-битные блоки и шифрует их с использованием 56-битного ключа, производя 64-разрядный вывод в классическом случае без заполнения или нулевого заполнения. Ваша реализация должна использовать побитовые операции над 8 байтовыми массивами, а не шестнадцатеричные представления строк длиной 16 или char[32], как и в ваших перестановках. Очевидно, что перестановки, сдвиги или вращения массивов char размером 16 или 32 не являются идемпотентными с теми же операциями над 64-битными значениями, описанными в алгоритме, и должны быть сделаны корректировки. Не только этот подход подвержен ошибкам, но и намного медленнее. Ответ на это означал бы отладку и исправление кода, который не соответствует цели этого сайта imho, и поскольку это выглядит как домашнее задание для меня (докажите, что я неправ), я собираюсь проповедовать эту небольшую обертку DESCryptoServiceProvider.

static class DesCsp 
{ 

    public static byte[] EncryptBytes(byte[] input, byte[] desKey, byte[] desIV) 
    { 
    DES des = new DESCryptoServiceProvider(); 
    des.Padding = PaddingMode.None; 
    var enc = des.CreateEncryptor(desKey, desIV); 
    return enc.TransformFinalBlock (input, 0, input.Length);  
    } 

    public static byte[] DecryptBytes(byte[] encryptedOutput, byte[] desKey, byte[] desIV) 
    { 
    DES des = new DESCryptoServiceProvider(); 
    des.Padding = PaddingMode.None; 
    var dec = des.CreateDecryptor(desKey, desIV); 
    return dec.TransformFinalBlock(encryptedOutput, 0, encryptedOutput.Length); 
    } 

    public static string EncryptHexStrings(string input, byte[] desKey, byte[] desIV) 
    { 
    byte[] bytes = HexStringToByteArray(input); 
    byte[] encBytes = EncryptBytes (bytes,desKey,desIV); 
    return ByteArrayToHexString(encBytes); 
    } 

    public static string DecryptHexStrings(string encryptedOutput, byte[] desKey, byte[] desIV) 
    { 
    byte[] bytes = HexStringToByteArray(encryptedOutput); 
    byte[] decBytes = DecryptBytes(bytes,desKey,desIV); 
    return ByteArrayToHexString(decBytes); 
    } 

    public static string EncryptHexStrings(string input, string desKey, string desIV) 
    { 
    byte[] key = HexStringToByteArray(desKey); 
    byte[] iv = HexStringToByteArray(desIV); 
    return EncryptHexStrings(input, key, iv); 
    } 

    public static string DecryptHexStrings(string encryptedOutput, string desKey, string desIV) 
    { 
    byte[] key = HexStringToByteArray(desKey); 
    byte[] iv = HexStringToByteArray(desIV); 
    return DecryptHexStrings(encryptedOutput,key,iv); 
    } 

    public static byte[] HexStringToByteArray(string s) 
    { 
    byte[] ret = new byte[s.Length/2]; 
    for (int i=0; i<s.Length; i+=2) 
    { 
     ret[i/2] = Convert.ToByte (s.Substring (i,2), 16);  
    } 
    return ret; 
    } 

    public static string ByteArrayToHexString(byte[] bytes) 
    { 
    StringBuilder sb = new StringBuilder(); 
    foreach (byte b in bytes) 
     sb.AppendFormat("{0:X2}", b); 
    return sb.ToString(); 
    } 

} 

Проверьте это, как это, с вашими данными:

// the encryption output should be: da02ce3a89ecac3b 
// But I'm getting this output instead: 019945B853663D50 
string inputString = "02468aceeca86420"; 
string stringkey = "0f1571c947d9e859"; 
string encryptedReference = "da02ce3a89ecac3b"; 
string siv = "0000000000000000"; 
encryptedString = DesCsp.EncryptHexStrings(inputString, stringkey, siv); 
decryptedString = DesCsp.DecryptHexStrings(encryptedString, stringkey, siv); 
Debug.Assert(inputString.ToUpper() == decryptedString.ToUpper()); 
Debug.Assert(encryptedString.ToUpper() == encryptedReference.ToUpper()); 

Алгоритмы симметричного шифрования в System.Security.Cryptography также вектор инициализации, но вам не нужно беспокоиться об этом. Так же, как этот обертка , вы можете использовать свой метод EncryptBytes(byte[] input, byte[] desKey) повсюду. Для вашего public static string EncryptHexStrings(string input, string desKey) вы должны адаптировать входную строку к массиву байтов, зашифровать ее как байты, вывести шестнадцатеричную строку из зашифрованных байтов при возврате.

+0

Благодарим вас за реализацию и за приятное объяснение. Я пытался построить DES с нуля, не используя встроенную библиотеку криптографии, но это тоже помогло мне. – WT86

0

Это почти полный код начинающий, как я, начинаю учиться использовать DES. Как насчет внесения некоторых исправлений, чтобы каждый не мог выполнять ту же работу по отладке и исправлению (или лучше, если они это делают). Некоторые из помогающих ссылок исчезли, но что-то полезное там. Я использовал http://page.math.tu-berlin.de/~kant/teaching/hess/krypto-ws2006/des.htm и http://people.eku.edu/styere/Encrypt/JS-DES.html (с модифицированной не только для чтения)

  • первый ключ должен быть последним клавиши [15] и каждый последующий является клавиши [I-1]
  • strtoBin очень плохой там. После удаления ее там лучше выводятся непосредственно из binarray SBoxSubstitution путем формирования выходного Res как res += Convert.ToString(s1, 2).PadLeft(4, '0'); в первом , если (я == 1) и так далее
  • последнего номера в expanstionArr должен быть 0 конечно

После этих трех модификаций я получил DESEncryption.

А что вы знаете ... дешифрование слишком работает без какого-либо другого ремонта :) Для этого скопируйте все DESEncryption в «DESDecryption» и изменить только (int j = 0; j < 16; j++) к for (int j = 15; j >= 0; j--)

Смежные вопросы