关于实现C#8字节的DES加密算法(DESCryptoServiceProvider)

 1.参考资料

(1)原理

加密与安全:对称加密算法 DES 与 3DES 加解密原理浅析:https://blog.csdn.net/liwei16611/article/details/84302020?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242

电子密本ECB和DES模式详解:https://blog.csdn.net/qq_34810707/article/details/88363890

(2)代码

<1>C语言

C语言实现C#下的DES加密算法:https://blog.csdn.net/u012339043/article/details/103856321

DES算法详解与源码:https://www.cnblogs.com/xiaoxiaff/p/3960302.html

 <2>C#

DES加密算法在C#下的实现:https://blog.csdn.net/subwo/article/details/372855

C#实现DES加密解密算法:https://www.cnblogs.com/null00/archive/2009/03/18/2065095.html

2.C#实现(8字节加密)

public class DES
{
    private static int[] C, D;
    private int[] R, L;
    public int[] Data;
    public int[] Ciphertext = new int[64];
    public static int[] Key;
    private static int[] Temp, Kong;
    public static int[,] ZiKeyS = new int[16, 48];
    private static int[] PC_1HE;
    private static int[] ShiftHE;
    private static int[] PC_2HE;
    private int[] IP_Output;
    private int[] IPHE;
    private int[] EHE;
    private int[,] SHE;
    private int[] PHE;
    private int[] FMethod;
    private int[] SHEOutput;
    private int[] PHEOutput;
    private int[] IP_1HE;
    private int[] XorOutput;
    public byte[] ciphertext = new byte[8];

    public DES()
    {
        C = new int[28] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        D = new int[28] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        R = new int[32] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        L = new int[32] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        XorOutput = new int[48]{14,17,11,24,1,5,3,28,15,6,21,10,23,19,12,4,26,8,16,7,27,20,13,2,41,52,31,37,47,55,30,40,51,45,
            33,48,44,49,39,56,34,53,46,42,50,36,29,32};
        FMethod = new int[48]{14,17,11,24,1,5,3,28,15,6,21,10,23,19,12,4,26,8,16,7,27,20,13,2,41,52,31,37,47,55,30,40,51,45,
            33,48,44,49,39,56,34,53,46,42,50,36,29,32};
        SHEOutput = new int[32] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        PHEOutput = new int[32] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        Data = new int[64]{58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,62,54,46,38,30,22,14,6,64,56,
                48,40,32,24,16,8,57,49,41,33,25,17,9,1,59,51,43,35,27,19,11,3,61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7};
        Key = new int[64] { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0 };
        IP_Output = new int[64] { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0 };
        PC_1HE = new int[56] {57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,2,59,51,43,35,27,19,11,3,60,52,44,36,63,55,47,39,
            31,23,15,7,62,54,46,38,30,22,14,6,61,53,45,37,29,21,13,5,28,20,12,4 };
        Temp = new int[56] {57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,2,59,51,43,35,27,19,11,3,60,52,44,36,63,55,47,39,
            31,23,15,7,62,54,46,38,30,22,14,6,61,53,45,37,29,21,13,5,28,20,12,4 };
        Kong = new int[56] {57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,2,59,51,43,35,27,19,11,3,60,52,44,36,63,55,47,39,
            31,23,15,7,62,54,46,38,30,22,14,6,61,53,45,37,29,21,13,5,28,20,12,4 };
        PC_2HE = new int[48]{14,17,11,24,1,5,3,28,15,6,21,10,23,19,12,4,26,8,16,7,27,20,13,2,41,52,31,37,47,55,30,40,51,45,
            33,48,44,49,39,56,34,53,46,42,50,36,29,32};

        ShiftHE = new int[16] { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
        SHE = new int[8, 64]{
            {
            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 },
            {
            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 },
            {
            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 },
            {
            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 },
            {
            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 },
            {
            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 },
            {
            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 },
            {
            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 }
            };
        IP_1HE = new int[64]{ 40,8,48,16,56,24,64,32,39,7,47,15,55,23,63,31,
            38,6,46,14,54,22,62,30,
            37,5,45,13,53,21,61,29,
            36,4,44,12,52,20,60,28,
            35,3,43,11,51,19,59,27,
            34,2,42,10,50,18,58,26,
            33,1,41,9, 49,17,57,25 };
        EHE = new int[48] {32,1,2,3,4,5,4,5,6,7,8,9,8,9,10,11,12,13,12,13,14,15,16,17,16,17,18,19,20,21,20,21,22,23,24,25,
            24,25,26,27,28,29,28,29,30,31,32,1 };
        PHE = new int[32] { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 };
        IPHE = new int[64]{58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,62,54,46,38,30,22,14,6,64,56,
                48,40,32,24,16,8,57,49,41,33,25,17,9,1,59,51,43,35,27,19,11,3,61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7};
    }

    public void Encryption(int flag, int count, ref byte[] data_1)
    {
        for (int n = 0; n < count; n++)
        {
            BTD(data_1, n);
            int[] IP_ip = new int[64] { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0 };
            int i;

            IP_Replace(flag);
            for (i = 0; i < 16; i++)
            {
                Ffunction(i, flag);
            }
            for (i = 0; i < 32; i++)
            {
                IP_ip[i] = L[i];
                IP_ip[i + 32] = R[i];
            }
            for (i = 0; i < 64; i++)
            {
                Ciphertext[i] = IP_ip[IP_1HE[i] - 1];
            }
            TTB(ref data_1, n);
        }
    }

    protected void Ffunction(int n, int flag)
    {
        int i;
        int[] Lzhongjian = new int[32] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

        for (i = 0; i < 48; i++)
        {
            FMethod[i] = R[EHE[i] - 1];
        }
        for (i = 0; i < 48; i++)
        {
            if (flag == 1)
            {
                XorOutput[i] = FMethod[i] ^ ZiKeyS[n, i];
            }
            else
            {
                XorOutput[i] = FMethod[i] ^ ZiKeyS[15 - n, i];
            }
        }
        SHE_Replace();

        for (i = 0; i < 32; i++)
        {
            PHEOutput[i] = SHEOutput[PHE[i] - 1];
        }
        for (i = 0; i < 32; i++)
        {
            Lzhongjian[i] = L[i];
            L[i] = R[i];
        }
        for (i = 0; i < 32; i++)
        {
            if (n != 15)
            {
                R[i] = Lzhongjian[i] ^ PHEOutput[i];
            }
            else
            {
                R[i] = L[i];
                L[i] = Lzhongjian[i] ^ PHEOutput[i];
            }
        }
    }

    protected void SHE_Replace()
    {
        int i, j, S_1, S_2;

        int[] S_S = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 };
        for (i = 0; i < 8; i++)
        {
            S_1 = XorOutput[i * 6] * 2 + XorOutput[i * 6 + 5];
            S_2 = XorOutput[i * 6 + 1] * 8 + XorOutput[i * 6 + 2] * 4 + XorOutput[i * 6 + 3] * 2 + XorOutput[i * 6 + 4];
            S_S[i] = SHE[i, S_1 * 16 + S_2];
        }
        for (i = 0; i < 8; i++)
        {
            for (j = 3; j >= 0; j--)
            {
                SHEOutput[i * 4 + j] = S_S[i] % 2;
                S_S[i] = S_S[i] / 2;
            }
        }
    }

    protected void IP_Replace(int flag)
    {
        int i;
        for (i = 0; i < 64; i++)
        {
            IP_Output[i] = Data[IPHE[i] - 1];
        }
        for (i = 0; i < 32; i++)
        {
            L[i] = IP_Output[i];
            R[i] = IP_Output[i + 32];
        }
    }

    public static void MiKey(byte[] key_1)
    {
        int i;
        BTK(key_1);
        PC_1();
        for (i = 0; i < 16; i++)
        {
            PC_2(ShiftHE[i], i);
        }
    }

    protected static void PC_1()
    {
        int i;
        for (i = 0; i < 56; i++)
        {
            Temp[i] = Key[PC_1HE[i] - 1];
        }
        for (i = 0; i < 28; i++)
        {
            C[i] = Temp[i];
            D[i] = Temp[i + 28];
        }
    }

    protected static void Shift_OP(int k)
    {
        int i;
        int a = C[0], b = C[1], c = D[0], d = D[1];
        if (k == 2)
        {
            for (i = 0; i < 26; i++)
            {
                C[i] = C[i + 2];
                D[i] = D[i + 2];
            }
            C[26] = a;
            C[27] = b;
            D[26] = c;
            D[27] = d;
        }
        else
        {
            for (i = 0; i < 27; i++)
            {
                C[i] = C[i + 1];
                D[i] = D[i + 1];
            }
            C[27] = a;
            D[27] = c;
        }
    }

    protected static void PC_2(int p, int LunCount)
    {
        int i;
        Shift_OP(p);
        for (i = 0; i < 28; i++)
        {
            Temp[i] = C[i];
            Temp[i + 28] = D[i];
        }
        for (i = 0; i < 48; i++)
        {
            ZiKeyS[LunCount, i] = Temp[PC_2HE[i] - 1];
        }
    }

    protected void BTD(byte[] data_1, int _count)
    {
        int i, j;
        int[] S_T_1 = new int[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
        for (i = 0; i < 8; i++)
        {
            S_T_1[i] = data_1[i + _count * 8];
            for (j = 0; j < 8; j++)
            {
                Data[i * 8 + 7 - j] = S_T_1[i] % 2;
                S_T_1[i] = S_T_1[i] / 2;
            }
        }
    }

    protected static void BTK(byte[] key_1)
    {
        int i, j;
        int[] S_T_1 = new int[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
        for (i = 0; i < 8; i++)
        {
            S_T_1[i] = key_1[i];
            for (j = 0; j < 8; j++)
            {
                Key[i * 8 + 7 - j] = S_T_1[i] % 2;
                S_T_1[i] = S_T_1[i] / 2;
            }
        }
    }

    protected void TTB(ref byte[] buffer, int _count)
    {
        int i, j;

        for (i = 0; i < 8; i++)
        {
            int zeng = 1;
            int jieguo = 0;
            for (j = 0; j < 8; j++)
            {
                if (j == 0)
                {
                    zeng = 1;
                }
                else
                {
                    zeng = zeng * 2;
                }
                jieguo += Ciphertext[i * 8 + 7 - j] * zeng;
            }
            buffer[i + _count * 8] = (byte)jieguo;
        }
    }
}
  internal sealed class Encryption
    {
        public static string EncryptDES(string paymnetCode, byte[] = null)
        {
            var bytesText = Encoding.UTF8.GetBytes(paymnetCode);
            int mod = bytesText.Length % 8;
            int sMod = 8 - mod;
            byte[] mByte = new byte[bytesText.Length + sMod];
            for (int i = 0; i < bytesText.Length; i++)
            {
                mByte[i] = bytesText[i];
            }
            for (int i = bytesText.Length; i < mByte.Length; i++)
            {
                mByte[i] = (byte)sMod;
            }
            //==============================================================//
            if (key == null) key = Encoding.ASCII.GetBytes("默认网站密钥");
            byte[] keybuffer = new byte[8];
            for (int i = 0; i < keybuffer.Length; i++)
            {
                keybuffer[i] = i < key.Length ? key[i] : (byte)0;
            }
            //==============================================================//
            DES des = new DES();
            DES.MiKey(keybuffer);
            //==============================================================//
            int div = mByte.Length / 8;
            if ((mByte.Length % 8) != 0) div += 1;
            byte[][] divmbyte = new byte[div][];
            for (int i = 0; i < div; i++)
            {
                divmbyte[i] = new byte[8];
                divmbyte[i][0] = mByte[i * 8 + 0];
                divmbyte[i][1] = mByte[i * 8 + 1];
                divmbyte[i][2] = mByte[i * 8 + 2];
                divmbyte[i][3] = mByte[i * 8 + 3];
                divmbyte[i][4] = mByte[i * 8 + 4];
                divmbyte[i][5] = mByte[i * 8 + 5];
                divmbyte[i][6] = mByte[i * 8 + 6];
                divmbyte[i][7] = mByte[i * 8 + 7];
            }
            byte[][] divcint = new byte[div][];
            for (int i = 0; i < div; i++)
            {
                divcint[i] = new byte[8];
                des.Encryption(1, 1, ref divmbyte[i]);
                divcint[i] = divmbyte[i];
            }
            byte[] cint = new byte[div * 8];
            for (int i = 0; i < div; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    cint[i * 8 + j] = divcint[i][j];
                }
            }
            return Convert.ToBase64String(cint);
        }
    }

 

posted @ 2021-07-21 10:45  微臣做不到  阅读(490)  评论(0编辑  收藏  举报