检索加密的富文本文件并将其显示在RichTextBox中

时间:2010-04-08 13:33:44

标签: c# rtf encryption richtext

好的,我需要的是将富文本框中键入的内容保存到文件中,加密,并再次从文件中检索文本并将其显示回富文本框。这是我的保存代码。

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“Stream不支持搜索。”

有关如何从加密文件加载数据并将其显示在富文本框中的任何建议?

3 个答案:

答案 0 :(得分:1)

由于您从未关闭保存中的CryptoStream,因此从未调用FlushFinalBlock来完成数据写入。因此,并非所有数据都已保存。

答案 1 :(得分:1)

您的IV和Key永远不会写入文件中(从您的save_cmd判断)

同样适用于你的开场白。你的(“关键”流和你的文件在任何地方......)之间没有任何链接

更新:

以下是您的代码的更好版本:

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

    }

有效。

答案 2 :(得分:0)

好的,我完成了我想要达到的目标。我的代码中有几个关键失败...... 首先,感谢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); 



    }