DES 加密仅适用于硬编码的位数组,但在读取文件时.txt失败

本文关键字:读取 文件 失败 txt 数组 适用于 加密 编码 DES | 更新日期: 2023-09-27 18:35:46

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

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

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

我认为问题在于我从StringList<BitArray>的转换,因为在遵循站点示例时,我将消息和键值硬编码为BitArray。尽管在创建以byte作为值的新BitArray时,它会将值转过来,这意味着最高有效位在左侧,但我的所有代码都已调整为此。

我知道这是很多代码,但请记住,如果我使用此站点上的硬编码位,此代码确实有效。

以下是我获得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Õ¸结果,这不是我想要的。

DES 加密仅适用于硬编码的位数组,但在读取文件时.txt失败

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

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 实现上。