0

我知道这似乎是一个模糊的问题,但我需要了解 DES en c# 的人的帮助。

我有一个项目可以手动进行 DES 加密,而无需使用 .NET 框架中的任何内置库。这非常重要,所以我不需要任何建议,例如使用该扩展的这个库:)

我一直在关注这个例子:说明 DES 算法,一切正常,经过 16 次迭代后,我得到了该站点上所示的结果。

我认为问题出在我从Stringto的转换中,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Õ¸的结果不是我想要的。

4

1 回答 1

0

这不是一个答案,而是写一些单元测试(我知道我在滥用这个词)。你的第一个测试应该是这样的:

BitArray inputData = BitarrayFromRandomData();
var encryptedBits = DesEncryptor.Encrypt(inputData, key);
BitArray outputData = DesEncryptor.Decrypt(outputData, key);

如果内容outputData匹配,inputData则问题的内容不在 DES 实现中。下一个测试是看字节和位之间转换的代码

byte[] inputData = ByteArrayFromRandomData();
BitArray intermediateData = BitarrayHelpers.FromByteArray(inputData);
byte[] outputData = BitArrayHelpers.ToByteArray(intermediateData);

请注意这里没有加密步骤,因为我们已经在第一次测试中排除了这一点。为字符串和字节数组之间的转换编写一个类似的测试,并进行涵盖整个事情的最终测试,一旦前三个通过,最后一个也应该通过。

这将使您能够将注意力(和 SO 问题)集中在损坏的代码上,而不是整个 DES 实现上。

于 2013-10-17T22:09:16.693 回答