关于实现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); } }