Получение зашифрованного файла Rich Text и его отображение в RichTextBox - PullRequest
1 голос
/ 08 апреля 2010

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

private void cmdSave_Click(object sender, EventArgs e)
{
    FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write);

    AesCryptoServiceProvider aes = new AesCryptoServiceProvider();

    aes.GenerateIV();
    aes.GenerateKey();
    aes.Mode = CipherMode.CBC;

    TextWriter twKey = new StreamWriter("key");
    twKey.Write(ASCIIEncoding.ASCII.GetString(aes.Key));
    twKey.Close();

    TextWriter twIV = new StreamWriter("IV");
    twIV.Write(ASCIIEncoding.ASCII.GetString(aes.IV));
    twIV.Close();

    ICryptoTransform aesEncrypt = aes.CreateEncryptor();

    CryptoStream cryptoStream = new CryptoStream(fs, aesEncrypt, CryptoStreamMode.Write);

    richTextBox1.SaveFile(cryptoStream, RichTextBoxStreamType.RichText);
}

Я знаю последствия безопасности для сохранения ключа и iv в файле, но это только для тестирования:)

Хорошо, сохраняющая часть работает нормально, что означает отсутствие исключений ... Файл создается в filePath, а ключ и файлы IV также создаются отлично ...

ОК, теперь можно найти часть, где я застрял: S

private void cmdOpen_Click(object sender, EventArgs e)
{
    OpenFileDialog openFile = new OpenFileDialog();

    openFile.ShowDialog();

    FileStream openRTF = new FileStream(openFile.FileName, FileMode.Open, FileAccess.Read);

    AesCryptoServiceProvider aes = new AesCryptoServiceProvider();

    TextReader trKey = new StreamReader("key");
    byte[] AesKey = ASCIIEncoding.ASCII.GetBytes(trKey.ReadLine());

    TextReader trIV = new StreamReader("IV");
    byte[] AesIV = ASCIIEncoding.ASCII.GetBytes(trIV.ReadLine());

    aes.Key = AesKey;
    aes.IV = AesIV;

    ICryptoTransform aesDecrypt = aes.CreateDecryptor();

    CryptoStream cryptoStream = new CryptoStream(openRTF, aesDecrypt, CryptoStreamMode.Read);

    StreamReader fx = new StreamReader(cryptoStream);

    richTextBox1.Rtf = fx.ReadToEnd();

    //richTextBox1.LoadFile(fx.BaseStream, RichTextBoxStreamType.RichText);        
} 

Но richTextBox1.Rtf = fx.ReadToEnd(); вызывает криптографическое исключение «Заполнение недопустимо и не может быть удалено».

, в то время как richTextBox1.LoadFile(fx.BaseStream, RichTextBoxStreamType.RichText); выдает NotSupportedException «Поток не поддерживает поиск».

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

Ответы [ 3 ]

1 голос
/ 08 апреля 2010

Ваш IV и ключ никогда не записываются в файл для начала (судя по вашему save_cmd)

И то же самое касается вашего открытия. ВСЕГО нет никакой связи между вашим (потоком «Key» и вашим файлом где-либо ...)

Обновлено:

Вот лучшая версия вашего кода:

        private void button1_Click(object sender, EventArgs e)
    {


        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();

        aes.GenerateIV();
        aes.GenerateKey();
        aes.Mode = CipherMode.CBC;


        File.WriteAllBytes("Key",aes.Key);
        File.WriteAllBytes("IV",aes.IV);


        ICryptoTransform aesEncrypt = aes.CreateEncryptor();
        using (FileStream fs = new FileStream("file.crypt", FileMode.Create, FileAccess.Write))
        {
            using (CryptoStream cryptoStream = new CryptoStream(fs, aesEncrypt, CryptoStreamMode.Write))
            {

                richTextBox1.SaveFile(cryptoStream, RichTextBoxStreamType.RichText);
            }
        }

    }

       private void button2_Click(object sender, EventArgs e)
    {
        OpenFileDialog openFile = new OpenFileDialog();

        openFile.ShowDialog();



        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();


        byte[] AesKey = File.ReadAllBytes("Key");
        byte[] AesIV = File.ReadAllBytes("IV");

        aes.Key = AesKey;
        aes.IV = AesIV;

        ICryptoTransform aesDecrypt = aes.CreateDecryptor();
        using (FileStream openRTF = new FileStream(openFile.FileName, FileMode.Open, FileAccess.Read))
        {
            using (CryptoStream cryptoStream = new CryptoStream(openRTF, aesDecrypt, CryptoStreamMode.Read))
            {

                using (StreamReader fx = new StreamReader(cryptoStream))
                {
                    richTextBox1.Rtf = fx.ReadToEnd();
                }
            }
        }

    }

Работает.

1 голос
/ 08 апреля 2010

Так как вы никогда не закрывали CryptoStream в Save, он никогда не вызывал FlushFinalBlock для завершения записи данных. Поэтому не все данные были сохранены.

0 голосов
/ 08 апреля 2010

ОК, я отлично достиг того, чего хотел достичь. В моем коде было несколько ключевых сбоев ... Во-первых, спасибо SLaks и Jipy, я понял, что "ты должен закрыть все открытые потоки":)

И вторая крупная ошибка, которую я совершил, была попытка сохранить ключ и iv в файле, где сохранение или загрузка обратно не работали! Таким образом, у меня было всего два байта [] для сохранения ключа и IV

Я изменил схему заполнения на ISO10126 и убедился, что режимом был CBC при выполнении команд открытия и закрытия.

И еще мне нужно было добавить код для открытия команды, и это сработало :) :):)

        StreamReader fx = new StreamReader(cryptoStream);

        fx.Read(fileContent, 0, Convert.ToInt32(fileContent.Length));

        fx.Close();

        cryptoStream.Close();

        richTextBox1.Rtf = new String(fileContent);

В любом случае приветствуются любые другие глупые проблемы с производительностью:)

Вот полные команды открытия и закрытия для всех, кто заинтересован.

    byte[] globalKey = new byte[32];
    byte[] globalIV = new byte[16];

    private void cmdSave_Click(object sender, EventArgs e)
    {


        FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write);

        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();

        aes.GenerateIV();
        aes.GenerateKey();
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.ISO10126;

        globalKey = aes.Key;
        globalIV = aes.IV;


        ICryptoTransform aesEncrypt = aes.CreateEncryptor();

        CryptoStream cryptoStream = new CryptoStream(fs, aesEncrypt, CryptoStreamMode.Write);

        richTextBox1.SaveFile(cryptoStream, RichTextBoxStreamType.RichText);

        cryptoStream.Close();
        fs.Close();

        richTextBox1.Clear();


    }

    private void cmdOpen_Click(object sender, EventArgs e)
    {
        OpenFileDialog openFile = new OpenFileDialog();

        openFile.ShowDialog();

        FileStream openRTF = new FileStream(openFile.FileName, FileMode.Open, FileAccess.Read);

        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();


        aes.Key = globalKey;
        aes.IV = globalIV;
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.ISO10126;


        ICryptoTransform aesDecrypt = aes.CreateDecryptor();

        CryptoStream cryptoStream = new CryptoStream(openRTF, aesDecrypt, CryptoStreamMode.Read);

        FileInfo fileNFO = new FileInfo(openFile.FileName);

        char[] fileContent = new char[fileNFO.Length];

        StreamReader fx = new StreamReader(cryptoStream);

        fx.Read(fileContent, 0, Convert.ToInt32(fileContent.Length));

        fx.Close();

        cryptoStream.Close();

        richTextBox1.Rtf = new String(fileContent); 



    } 
...