Что не так с моей оберткой Triple DES?

похоже, что мой код добавляет 6 байтов в файл результата после вызова дешифрования шифрования .. я пробую его в файле mkv .. пожалуйста, помогите

вот мой код

class TripleDESCryptoService : IEncryptor, IDecryptor
{
    public void Encrypt(string inputFileName, string outputFileName, string key)
    {
        EncryptFile(inputFileName, outputFileName, key);
    }

    public void Decrypt(string inputFileName, string outputFileName, string key)
    {
        DecryptFile(inputFileName, outputFileName, key);
    }

    static void EncryptFile(string inputFileName, string outputFileName, string sKey)
    {
        var outFile = new FileStream(outputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);

        // The chryptographic service provider we're going to use
        var cryptoAlgorithm = new TripleDESCryptoServiceProvider();
        SetKeys(cryptoAlgorithm, sKey);

        // This object links data streams to cryptographic values
        var cryptoStream = new CryptoStream(outFile, cryptoAlgorithm.CreateEncryptor(), CryptoStreamMode.Write);

        // This stream writer will write the new file
        var encryptionStream = new BinaryWriter(cryptoStream);

        // This stream reader will read the file to encrypt
        var inFile = new FileStream(inputFileName, FileMode.Open, FileAccess.Read);
        var readwe = new BinaryReader(inFile);

        // Loop through the file to encrypt, line by line
        var date = readwe.ReadBytes((int)readwe.BaseStream.Length);


        // Write to the encryption stream
        encryptionStream.Write(date);


        // Wrap things up
        inFile.Close();
        encryptionStream.Flush();
        encryptionStream.Close();
    }

    private static void SetKeys(SymmetricAlgorithm algorithm, string key)
    {
        var keyAsBytes = Encoding.ASCII.GetBytes(key);
        algorithm.IV = keyAsBytes.Take(algorithm.IV.Length).ToArray();
        algorithm.Key = keyAsBytes.Take(algorithm.Key.Length).ToArray();
    }

    static void DecryptFile(string inputFilename, string outputFilename, string sKey)
    {
        // The encrypted file
        var inFile = File.OpenRead(inputFilename);

        // The decrypted file
        var outFile = new FileStream(outputFilename, FileMode.OpenOrCreate, FileAccess.ReadWrite);

        // Prepare the encryption algorithm and read the key from the key file
        var cryptAlgorithm = new TripleDESCryptoServiceProvider();

        SetKeys(cryptAlgorithm, sKey);

        // The cryptographic stream takes in the encrypted file
        var encryptionStream = new CryptoStream(inFile, cryptAlgorithm.CreateDecryptor(), CryptoStreamMode.Read);

        // Write the new unecrypted file
        var cleanStreamReader = new BinaryReader(encryptionStream);
        var cleanStreamWriter = new BinaryWriter(outFile);
        cleanStreamWriter.Write(cleanStreamReader.ReadBytes((int)inFile.Length));
        cleanStreamWriter.Close();
        outFile.Close();
        cleanStreamReader.Close();
    }
}

person Chen Kinnrot    schedule 30.03.2010    source источник


Ответы (4)


Ваш код не добавляет шесть байтов, 3DES округляет до полного размера блока. Так работают блочные шифры. Вы увидите это только в результирующем зашифрованном тексте, но не в расшифрованном открытом тексте.

Опять же, не о чем беспокоиться, блочные шифры должны дополнить ваш открытый текст до следующего размера блока, прежде чем он сможет зашифровать открытый текст. При расшифровке зашифрованного текста отступы удаляются.

Кроме того, я провел быстрый обзор кода, и у вас есть ошибка в коде - вы используете один и тот же ключ для IV и ключа, и вам действительно следует использовать разные данные. Поэтому я бы добавил еще один аргумент в DecryptFile (), EncryptFile () и SetKeys (), чтобы разрешить другой IV.

person Michael Howard-MSFT    schedule 30.03.2010
comment
что это за IV, и они не совпадают, потому что размер не тот, IV - 8 байт, а ключ - 24 байта .. в расшифрованном файле есть лишние 6 байтов, стоит ли беспокоиться и вырезать его? - person Chen Kinnrot; 30.03.2010
comment
Вектор инициализации - он используется в некоторых режимах блочного шифрования, таких как Cipher Block Chaining (CBC) - не беспокойтесь об этом слишком сильно! Просто убедитесь, что это не то же самое, что и ключ - а это означает совершенно другое, используйте отдельное случайное число, чем ключ. Итак, единственное изменение, которое я сделал для тестирования вашего кода, - это удаление IEncryptor и IDecryptor, потому что их нет в .NET Framework - что они собой представляют? - person Michael Howard-MSFT; 30.03.2010

Я не знаю, какой режим шифрования вы используете, но режимы ECB и CBC добавляют биты заполнения в конце последнего блока, чтобы увеличить его размер до 64 бит. Может отсюда твои байты?

person Juri Robl    schedule 30.03.2010
comment
если я воспользуюсь другим режимом, этого не произойдет? - person Chen Kinnrot; 30.03.2010

Tiple-DES - это 64-битный блочный шифр. Не анализируя ваш код, я предполагаю, что ваши данные не выровнены по 64-битной системе и что они были дополнены тегом режим PKCS7 по умолчанию.

person Jonas Elfström    schedule 30.03.2010

Я просмотрел код и не обнаружил никаких проблем, но я не очень хорошо знаком с используемыми вами классами, поэтому могу ошибаться. Вместо этого я дам несколько общих советов, касающихся любой ошибки:

Попытайтесь выследить проблему. Во многих строках кода сложно найти ошибку. Создайте максимально короткий код, отображающий ошибочное поведение.

Например, попробуйте записать строку в выходной поток. Правильный размер?

  • Если нет, значит, вы почти нашли проблему - что-то не так с записью файла, шифрование не имеет никакого отношения к проблеме.
  • Если да, продолжайте добавлять функции небольшими шагами, пока не обнаружите проблему.

Это стандартный метод отладки и чрезвычайно полезный, я предлагаю использовать его каждый раз, когда вы сталкиваетесь с проблемой.

Помимо этого, старайтесь всегда иметь чистые стартовые условия, то есть убедитесь, что записанный файл был удален. Попробуйте использовать свой код на разных входах и посмотрите, не дает ли он каждый раз один и тот же результат или есть ли различия.

Изменить:

Согласно другим ответам, у вас проблемы с 64-битным блоком. С помощью идей, описанных ранее, вы можете легко исключить многие другие факторы, пока не останется только само шифрование.

Затем вы можете спросить: «Почему TripeDES добавляет на вход до 7 байтов?» что было бы гораздо более ясным вопросом, чем "Что не так с моей оболочкой Triple DES ??" - и вы наверняка получили бы ответ на этот простой вопрос меньше чем за минуту!

person mafu    schedule 30.03.2010