我知道这似乎是一个模糊的问题,但我需要了解 DES en c# 的人的帮助。
我有一个项目可以手动进行 DES 加密,而无需使用 .NET 框架中的任何内置库。这非常重要,所以我不需要任何建议,例如使用该扩展的这个库:)
我一直在关注这个例子:说明 DES 算法,一切正常,经过 16 次迭代后,我得到了该站点上所示的结果。
我认为问题出在我从String
to的转换中,List<BitArray>
因为在按照网站上的示例进行操作时,我将消息和键值硬编码为BitArray
. BitArray
尽管在使用as 值创建一个新byte
值时,它会改变值,这意味着最高有效位在左侧,但我的所有代码都已调整为此。
我知道这是很多代码,但请记住,如果我使用在此站点上找到的硬编码位,则此代码确实有效。
这是我得到的方法List<BitArray>
:
private List<BitArray> splitFileIntoBlocksOf8Bytes()
{
String bericht; //Nog niet van toepassing, maar legt het principe van feedback weer ;)
List<BitArray> lstByteBlocks = splitByteArray8(Streamers.getFileInBytes(strPathForSourceFile));
if (lstByteBlocks.Count == 0)
bericht = "Het bestand dat u gekozen heeft is een leeg bestand";
return lstByteBlocks;
}
//NOTICE how I turn each byte array around and revers the BitArray so it matches the logic found on the site!
private List<BitArray> splitByteArray8(byte[] arrBytes)
{
List<BitArray> lstChunks = new List<BitArray>();
byte[] chunkOfBytes = new byte[8];
try
{
for (int byteAdded = 0; byteAdded < arrBytes.Length; byteAdded += 8)
{
Array.Copy(arrBytes, 0 + byteAdded, chunkOfBytes, 0, 8);
Array.Reverse(chunkOfBytes);
lstChunks.Add(Arrays.ReverseBitArray(new BitArray(chunkOfBytes)));
}
}
catch (ArgumentException)
{
BitArray addedBits = new BitArray(64);
chunkOfBytes = new byte[8];
int bitsToAdd = (int) Convert.ToInt32(64 - (Math.Ceiling(arrBytes.Length % 8.0) * 8));
for (int bitAdded = 0; bitAdded < (arrBytes.Length * 8 - bitsToAdd); bitAdded++)
{
addedBits[bitAdded] = true;
}
Array.Copy(arrBytes, (arrBytes.Length - ((64 - bitsToAdd) / 8)), chunkOfBytes, 0, ((64 - bitsToAdd) / 8));
lstChunks.Add(new BitArray(chunkOfBytes));
lstChunks.Add(addedBits);
}
return lstChunks;
}
这是迭代代码(每个块都通过这个函数:
//lstEncodedFile = new List<byte[]>();
BitArray arrBlock = (BitArray)((object[]) args)[0];
BitArray arrPremutedBlock = initialPremutation(arrBlock, Arrays.InitielePremutatieArray);
BitArray arrLeftBits = new BitArray(32);
BitArray arrRightBits = new BitArray(32);
BitArray arrTempLeft;
for (int bitCounter = 0; bitCounter < 32; bitCounter++)
{
arrLeftBits.Set(bitCounter, arrPremutedBlock.Get(bitCounter));
arrRightBits.Set(bitCounter, arrPremutedBlock.Get(bitCounter + 32));
}
int intStartIteratie = 0, intStopIteratie = 16, intStapIteratie = 1;
if (cryptType == CryptType.DECRYPT)
{
intStartIteratie = 15;
intStopIteratie = -1;
intStapIteratie = -1;
}
for (int intIteratie = intStartIteratie; intIteratie != intStopIteratie; intIteratie += intStapIteratie) // 15 iteraties
{
arrTempLeft = arrLeftBits;
arrLeftBits = arrRightBits; //Li = R(i-1)
arrRightBits = arrTempLeft.Xor(feistel.getFeistelResult(Arrays.ExpandBitArray(arrRightBits), intIteratie)); // Ri = L(i-1) XOR f(Ri, K(i+1))
}
BitArray arrIterationResult = new BitArray(64);
for (int bitCounter = 0; bitCounter < 32; bitCounter++)
{
arrIterationResult.Set(bitCounter, arrRightBits.Get(bitCounter));
arrIterationResult.Set(bitCounter + 32, arrLeftBits.Get(bitCounter));
}
byte[] byteResult = new byte[8];
BitArray arrResult = initialPremutation(arrIterationResult, Arrays.LaatstePremutatieArray);
arrResult.CopyTo(byteResult, 0);
lstCodedFile.Insert(intBlockCounter++, byteResult);
如果您还没有发现任何错误,这里是 feistel 函数:
public BitArray getFeistelResult(BitArray arrHalfBlock, int indexSubSleutel)
{
BitArray Subkey = lijstSubkeys[indexSubSleutel];
BitArray XoredHalfBlockAndSubkey = arrHalfBlock.Xor(Subkey);
BitArray Result = Sboxen(XoredHalfBlockAndSubkey);
return Result;
}
和 Sboxen 函数:
private BitArray Sboxen(BitArray array)
{
List<int> lijsStartIndex = new List<int>();
int sbox1Startindex = 5;
int sbox2Startindex = 11;
int sbox3Startindex = 17;
int sbox4Startindex = 23;
int sbox5Startindex = 29;
int sbox6Startindex = 35;
int sbox7Startindex = 41;
int sbox8Startindex = 47;
#region SBOXEN genereren
//haal telkens de waarde uit de array van 48 bits en maak telkens een sbox ervan
BitArray Sbox1 = GenerateSbox(array.Get(sbox1Startindex),
array.Get(sbox1Startindex - 1),
array.Get(sbox1Startindex - 2),
array.Get(sbox1Startindex - 3),
array.Get(sbox1Startindex - 4),
array.Get(sbox1Startindex - 5));
BitArray Sbox2 = GenerateSbox(array.Get(sbox2Startindex),
array.Get(sbox2Startindex - 1),
array.Get(sbox2Startindex - 2),
array.Get(sbox2Startindex - 3),
array.Get(sbox2Startindex - 4),
array.Get(sbox2Startindex - 5));
BitArray Sbox3 = GenerateSbox(array.Get(sbox3Startindex),
array.Get(sbox3Startindex - 1),
array.Get(sbox3Startindex - 2),
array.Get(sbox3Startindex - 3),
array.Get(sbox3Startindex - 4),
array.Get(sbox3Startindex - 5));
BitArray Sbox4 = GenerateSbox(array.Get(sbox4Startindex),
array.Get(sbox4Startindex - 1),
array.Get(sbox4Startindex - 2),
array.Get(sbox4Startindex - 3),
array.Get(sbox4Startindex - 4),
array.Get(sbox4Startindex - 5));
BitArray Sbox5 = GenerateSbox(array.Get(sbox5Startindex),
array.Get(sbox5Startindex - 1),
array.Get(sbox5Startindex - 2),
array.Get(sbox5Startindex - 3),
array.Get(sbox5Startindex - 4),
array.Get(sbox5Startindex - 5));
BitArray Sbox6 = GenerateSbox(array.Get(sbox6Startindex),
array.Get(sbox6Startindex - 1),
array.Get(sbox6Startindex - 2),
array.Get(sbox6Startindex - 3),
array.Get(sbox6Startindex - 4),
array.Get(sbox6Startindex - 5));
BitArray Sbox7 = GenerateSbox(array.Get(sbox7Startindex),
array.Get(sbox7Startindex - 1),
array.Get(sbox7Startindex - 2),
array.Get(sbox7Startindex - 3),
array.Get(sbox7Startindex - 4),
array.Get(sbox7Startindex - 5));
BitArray Sbox8 = GenerateSbox(array.Get(sbox8Startindex),
array.Get(sbox8Startindex - 1),
array.Get(sbox8Startindex - 2),
array.Get(sbox8Startindex - 3),
array.Get(sbox8Startindex - 4),
array.Get(sbox8Startindex - 5));
#endregion SBOXEN genereren
//deze functie gaat de int waarde ophalen uit Arrays.SBoxArrays
BitArray sbox1Value = new BitArray(getValueFromSbox(Sbox1, 0));
BitArray sbox2Value = new BitArray(getValueFromSbox(Sbox2, 1));
BitArray sbox3Value = new BitArray(getValueFromSbox(Sbox3, 2));
BitArray sbox4Value = new BitArray(getValueFromSbox(Sbox4, 3));
BitArray sbox5Value = new BitArray(getValueFromSbox(Sbox5, 4));
BitArray sbox6Value = new BitArray(getValueFromSbox(Sbox6, 5));
BitArray sbox7Value = new BitArray(getValueFromSbox(Sbox7, 6));
BitArray sbox8Value = new BitArray(getValueFromSbox(Sbox8, 7));
bool[] CombinedSboxen = new bool[32];
sbox1Value.CopyTo(CombinedSboxen, 0);
sbox2Value.CopyTo(CombinedSboxen, 4);
sbox3Value.CopyTo(CombinedSboxen, 8);
sbox4Value.CopyTo(CombinedSboxen, 12);
sbox5Value.CopyTo(CombinedSboxen, 16);
sbox6Value.CopyTo(CombinedSboxen, 20);
sbox7Value.CopyTo(CombinedSboxen, 24);
sbox8Value.CopyTo(CombinedSboxen, 28);
return Arrays.SBoxPremutatie(CombinedSboxen);
}
这是 getValueFromSbox 函数:
private BitArray getValueFromSbox(BitArray array, int WichSbox)
{
BitArray arrayRow = new BitArray(2);
BitArray arrayColumn = new BitArray(4);
arrayRow.Set(0, array.Get(0)); //de eerste en de laatste bit nemen voor de rij
arrayRow.Set(1, array.Get(5));
arrayColumn.Set(0, array.Get(1)); //de overige 4 bits voor de kolom
arrayColumn.Set(1, array.Get(2));
arrayColumn.Set(2, array.Get(3));
arrayColumn.Set(3, array.Get(4));
int Row = CalculateToInteger(Arrays.ReverseBitArray(arrayRow)); //lengte 2
int column = CalculateToInteger(Arrays.ReverseBitArray(arrayColumn)); // lengte 4
Byte b = Arrays.SBoxArrays[WichSbox, Row, column];
BitArray bit = new BitArray(BitConverter.GetBytes(b).ToArray());
BitArray SboxValue = new BitArray(4);
SboxValue.Set(0, bit.Get(3));
SboxValue.Set(1, bit.Get(2));
SboxValue.Set(2, bit.Get(1));
SboxValue.Set(3, bit.Get(0));
return SboxValue;
}
最后是 CalculateToInteger 函数:
private int CalculateToInteger(BitArray array)
{
double result = 0;
for (int counter = 0; counter < array.Count; counter++)
{
if (array[array.Length - 1 - counter] == true)
result += Math.Pow(2, counter);
}
return Convert.ToInt32(result);
}
编辑:加密0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
导致10000101 11101000 00010011 01010100 00001111 00001010 10110100 00000101
加密后,这是我想要的,
当加密 8 字节字符串时Testjeuh
,我得到Ô§”\YDÕ¸
的结果不是我想要的。