Расшифровка файла отсутствует ~ 10 символов от окончания

2

Я написал методы шифрования/дешифрования, используя RC2CryptoServiceProvider в С#, и по какой-то причине я не могу заставить дешифратор расшифровать последние несколько байтов. Файл, похоже, просто отключен. Мой метод шифрования выглядит следующим образом:

    public static byte[] EncryptString(byte[] input, string password)
    {
        PasswordDeriveBytes pderiver = new PasswordDeriveBytes(password, null);
        byte[] ivZeros = new byte[8];
        byte[] pbeKey = pderiver.CryptDeriveKey("RC2", "MD5", 128, ivZeros);

        RC2CryptoServiceProvider RC2 = new RC2CryptoServiceProvider();

        byte[] IV = new byte[8];
        ICryptoTransform encryptor = RC2.CreateEncryptor(pbeKey, IV);

        MemoryStream msEncrypt = new MemoryStream();
        CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
        csEncrypt.Write(input, 0, input.Length);
        csEncrypt.FlushFinalBlock();

        return msEncrypt.ToArray();
    }

Пока мое дешифрование выглядит следующим образом:

    public static byte[] DecryptString(byte[] input, string password, int originalSize)
    {
        PasswordDeriveBytes pderiver = new PasswordDeriveBytes(password, null);
        byte[] ivZeros = new byte[8];
        byte[] pbeKey = pderiver.CryptDeriveKey("RC2", "MD5", 128, ivZeros);

        RC2CryptoServiceProvider RC2 = new RC2CryptoServiceProvider();

        byte[] IV = new byte[8];
        ICryptoTransform decryptor = RC2.CreateDecryptor(pbeKey, IV);

        MemoryStream msDecrypt = new MemoryStream();
        CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write);

        csDecrypt.Write(input, 0, originalSize);
       // csDecrypt.FlushFinalBlock();

        char[] decrypted = new char[input.Length];
        decrypted = System.Text.Encoding.UTF8.GetChars(msDecrypt.ToArray());
        return msDecrypt.ToArray();

    }

char [] decrypted возвращает весь файл, дешифрованный, за исключением того, что файл заканчивается на </LudoData>, а при расшифровке я получаю только первый символ <.

Я играю с вещами и ничего не меняет. В моем конкретном случае input имеет длину 11296, а originalSize имеет размер 11290. Однако decrypted заканчивается размером 11280 при расшифровке. Что дает!

Теги:
encryption
cryptography

2 ответа

6
Лучший ответ

Есть ли причина, по которой вы отключили флеш()? Вы пытались полностью закрыть свои потоки?

  • 0
    Он пишет в оба криптопотока, что означает, что он должен очистить последний блок в обоих, это точно.
  • 0
    Я закомментировал это из-за ошибки во время выполнения, которую я получал, что я исправил, а затем забыл о Flush. Это как-то решило все. Я вообще не понимаю, но спасибо!
Показать ещё 1 комментарий
0

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

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

Шифрование:

var rij = RijndaelManaged.Create();
rij.Mode = CipherMode.CBC;
rij.BlockSize = 256;
rij.KeySize = 256;
rij.Padding = PaddingMode.ISO10126;
var pdb = new Rfc2898DeriveBytes(password, 
          Encoding.Default.GetBytes("lolwtfbbqsalt" + password));
var enc = rij.CreateEncryptor(pdb.GetBytes(rij.KeySize / 8), 
          pdb.GetBytes(rij.BlockSize / 8));
return enc.TransformFinalBlock(unencryptedBytes, 0, unencryptedBytes.Length);

Расшифровать:

// throws a cryptographic exception if password is wrong
var rij = RijndaelManaged.Create();
rij.Mode = CipherMode.CBC;
rij.BlockSize = 256;
rij.KeySize = 256;
rij.Padding = PaddingMode.ISO10126;
var pdb = new Rfc2898DeriveBytes(password, 
          Encoding.Default.GetBytes("lolwtfbbqsalt" + password));
var dec = rij.CreateDecryptor(pdb.GetBytes(rij.KeySize / 8), 
          pdb.GetBytes(rij.BlockSize / 8));
return dec.TransformFinalBlock(encryptedBytes, 0, 
          encryptedBytes.Length);

Обратите внимание, что единственное, что отличается от этих двух методов, это CreateEncryptor/CreateDecryptor, поэтому вы можете реорганизовать много дублирования. Также обратите внимание, что я попадаю в массив байтов и выхожу из массива байтов без использования каких-либо потоков. Это также немного более безопасно, чем RC2, и, тем более, если соль была бы более случайной.

  • 0
    Я использую RC2, потому что это также должно быть совместимо с приложением C ++, которое принимает зашифрованный файл RC2

Ещё вопросы

Сообщество Overcoder
Наверх
Меню