DES加密无效C#

时间:2014-11-07 07:44:59

标签: c# encryption des

我已经从头开始在C#中编写DES了,我会在这里发布整个代码,对我来说似乎是正确的但是当我尝试一个例子时它不是。这是我的整个代码。

Des Class:

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();
        }

}
}

关键班级:

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

我仔细检查过所有内容,我真的不知道我在这里做错了什么...请原谅我的杂乱代码,但它是在不到一天的时间内写的:/

感谢您的任何提示

3 个答案:

答案 0 :(得分:1)

加密测试向量(0F1571C947D9E859 02468ACEECA86420 DA02CE3A89ECAC3B)有效,我检查了符合标准的实现。

解决新DES实现问题的方法是将圆值与已知实现进行比较,例如使用产生舍入值的DES Calculator。您也可以复制已知良好的实现并将其修改为输出舍入值。它还意味着每轮为您的实现生成相同的值。

失败将显示在您的一个或多个排列,关键时间表或其移位方向或编程语言语法或语义的实现中。

当您处理1&0和0的字符串时,比较二进制结果会更容易。

还有谷歌代码上的DES的javascript实现: 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

答案 1 :(得分:0)

这是DES算法的实现,由NIST在出版物FIPS PUB 197中指定,可在NIST网站here上获得。该算法采用64位块并使用56位密钥加密它们,在经典情况下产生64位输出,没有填充或零填充。您的实现应该使用8字节数组的按位运算,而不是长度为16的十六进制字符串表示,或者像您在排列中那样使用char[32]。显然,对于大小为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),您需要将输入字符串调整为字节数组,将其加密为字节,并在返回时从加密字节中生成十六进制字符串。

答案 2 :(得分:0)

对于像我这样的初学者来说,这几乎是完全开始学习使用DES的完整代码。如何进行一些更正,以便每个人都不需要遵循相同的调试和修复工作(如果他们这样做,则更好)。一些帮助链接已经消失,但有一些有用的东西。我在用 http://page.math.tu-berlin.de/~kant/teaching/hess/krypto-ws2006/des.htmhttp://people.eku.edu/styere/Encrypt/JS-DES.html(修改后不是只读)

  • 第一个键必须是最后一个键[15] ,然后每个键都是键[i-1]
  • strtoBin 在那里非常错误。丢弃之后,通过在第一个中形成输出 res ,如{% set posts = __SELF__.posts %} <ul class="post-list"> {% for post in posts %} <li> <h3><a href="{{ post.url }}">{{ post.title }}</a></h3> <p class="info"> Posted {% if post.categories.count %} in {% endif %} {% for category in post.categories %} <a href="{{ category.url }}">{{ category.name }}</a>{% if not loop.last %}, {% endif %} {% endfor %} on {{ post.published_at|date('M d, Y') }} </p> <p class="excerpt">{{ post.summary }}</p> </li> {% else %} <li class="no-data">{{ noPostsMessage }}</li> {% endfor %} </ul> {% if posts.lastPage > 1 %} <ul class="pagination"> {% if posts.currentPage > 1 %} <li><a href="{{ this.page.baseFileName|page({ (pageParam): (posts.currentPage-1) }) }}">&larr; Prev</a></li> {% endif %} {% for page in 1..posts.lastPage %} <li class="{{ posts.currentPage == page ? 'active' : null }}"> <a href="{{ this.page.baseFileName|page({ (pageParam): page }) }}">{{ page }}</a> </li> {% endfor %} {% if posts.lastPage > posts.currentPage %} <li><a href="{{ this.page.baseFileName|page({ (pageParam): (posts.currentPage+1) }) }}">Next &rarr;</a></li> {% endif %} </ul> {% endif %} ,可以直接从 SBoxSubstitution 输出binarray if(i == 1)等等
  • expanstionArr 中的最后一个数字当然必须为0

经过这3次修改后,我得到了 DESEncryption

而你知道的......解密工作也没有任何其他修复:)为此你将整个 DESEncryption 复制到&#34; DESDecryption&#34; 和仅将res += Convert.ToString(s1, 2).PadLeft(4, '0');更改为(int j = 0; j < 16; j++)