C # Передача зашифрованных данных из файла в поток памяти.Бросив исключение - PullRequest
1 голос
/ 20 июля 2010

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

byte[] cipherText = File.ReadAllBytes(encryptedFile);

Затем передача этого байтового массива статическому методу bool, который вызывает фактический метод дешифрования и возвращает true, если не было выдано криптографическое исключение. В моей основной форме у меня есть нажатие кнопки, которая вызывает статический bool из оператора If, разблокирование некоторых дополнительных элементов интерфейса, если оно возвращается true, и вывод сообщения «неверный пароль», если он возвращает false.

Я прошел весь процесс, и он выдает «Заполнение недопустимо и не может быть удалено». исключение, которое обнаружил какой-то поиск, который должен произойти, если указан неправильный ключ дешифрования. Я знаю, что передаю тот же ключ, по крайней мере, набираю его, поэтому я предполагаю, что проблема связана либо с тем, как передается byte [], либо с самими потоками. Вот пример метода дешифрования:

public static string Decrypt(string password, byte[] ciphertext)
    {
        byte[] key, iv;
        CreateKeyIV(password, out key, out iv);
        using (MemoryStream encrypted = new MemoryStream(ciphertext))
        using (CryptoStream dec = new CryptoStream(encrypted, _algorithm.CreateDecryptor(key, iv), CryptoStreamMode.Read))
        using (StreamReader reader = new StreamReader(dec))
        {
            try
            {
                return reader.ReadToEnd();
            }
            catch (CryptographicException)
            {
                throw new CryptographicException("Invalid password.");
            }
            finally
            {
                encrypted.Close();
                dec.Close();
                reader.Close();
            }
        }
    }

Кто-нибудь видит, чего мне не хватает?

Ответы [ 2 ]

4 голосов
/ 20 июля 2010

Код расшифровки выглядит хорошо для меня, хотя я бы сделал несколько изменений:

  • Почему бы не передать поток или имя файла, а не зашифрованные данные в виде байтового массива?Нет необходимости читать все сразу, а затем обернуть данные в MemoryStream, когда вы можете просто использовать FileStream в качестве источника
  • Вам не нужно вызывать Close - эточто означают операторы использования для
  • Почему вы бросаете новый CryptographicException, который неправильно объяснил проблему, вместо того, чтобы допустить всплывание существующего исключения?

Другими словами, этоВот как будет выглядеть мой метод:

public static string Decrypt(string password, Stream encrypted)
{
    byte[] key, iv;
    CreateKeyIV(password, out key, out iv);
    using (CryptoStream dec = new CryptoStream(encrypted,
           _algorithm.CreateDecryptor(key, iv), CryptoStreamMode.Read))
    using (StreamReader reader = new StreamReader(dec))
    {
        return reader.ReadToEnd();
    }
 }

Однако вы показали, что не так в другом комментарии:

 // Bad code! Do not use!
 byte[] newCipher = Encryptor.Encrypt(newPass, newPass);
 string writeIt = System.Text.Encoding.UTF8.GetString(newCipher);

Вы искали зашифрованные данные.Результатом шифрования редко будет допустимая строка UTF-8.Вы должны просто записать его прямо на диск в двоичном формате , никогда не пытаясь преобразовать его в текст.Либо ваш код шифрования может сделать это напрямую, либо вы можете позвонить File.WriteAllBytes().Если вам абсолютно необходимо преобразовать произвольные двоичные данные в строку в какой-то момент, вы должны преобразовать их в base64, используя Convert.ToBase64String(data).Таким образом, вы можете позже получить те же двоичные данные, преобразовав их обратно.Попытка «расшифровать» его как текст является почти верным способом потери данных - как вы делаете здесь.

0 голосов
/ 20 июля 2010

Я не буду открывать StreamReader на CryptoStream, но на самом деле я вызову напрямую метод Read класса CryptoStream, передавая буфер byte[], в котором будут храниться расшифрованные данные.


Вот мой фрагмент.Я использовал его с MemoryStream и FileStream.

Stream s = ...;

ICryptoTransform cTransform = Encryptor.CreateDecryptor();
using (CryptoStream cStream = new CryptoStream(s, cTransform, CryptoStreamMode.Read)) {
byte[] mCryptoData = new byte[s.Length];
cStream.Read(mCryptoData, 0, mCryptoData.Length);
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...