Расшифровка файла отсутствует ~ 10 символов от окончания - PullRequest
2 голосов
/ 27 октября 2009

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

    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();

    }

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

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

Ответы [ 2 ]

6 голосов
/ 27 октября 2009

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

0 голосов
/ 27 октября 2009

Вздох, я сражался в этой битве около месяца назад, и у меня была очень похожая проблема, за исключением того, что я испытывал СЛИШКОМ много в конце. 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, и было бы еще более, если бы соль была более случайной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...