我已经从头开始在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
我仔细检查过所有内容,我真的不知道我在这里做错了什么...请原谅我的杂乱代码,但它是在不到一天的时间内写的:/
感谢您的任何提示
答案 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.htm 和 http://people.eku.edu/styere/Encrypt/JS-DES.html(修改后不是只读)
{% 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) }) }}">← 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 →</a></li>
{% endif %}
</ul>
{% endif %}
,可以直接从 SBoxSubstitution 输出binarray if(i == 1)等等经过这3次修改后,我得到了 DESEncryption 。
而你知道的......解密工作也没有任何其他修复:)为此你将整个 DESEncryption 复制到&#34; DESDecryption&#34; 和仅将res += Convert.ToString(s1, 2).PadLeft(4, '0');
更改为(int j = 0; j < 16; j++)