【问题标题】:Retrieving Encrypted Rich Text file and showing it in a RichTextBox检索加密的富文本文件并将其显示在 RichTextBox 中
【发布时间】:2010-04-08 13:33:43
【问题描述】:

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

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

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

【问题讨论】:

  • 您需要关闭您的信息流。
  • 这实际上没有帮助:(因为在到达关闭语句之前抛出异常
  • 是的;你还有其他问题。但是,您仍然需要关闭您的流。使用using 语句。
  • 谢谢!我从这个网址msdn.microsoft.com/en-us/library/yh598w02(VS.80).aspx 了解了“使用”语句的用法

标签: c# rtf encryption richtext


【解决方案1】:

您的 IV 和密钥从未写入文件开头(从您的 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();
                }
            }
        }

    }

有效。

【讨论】:

  • 密钥和 IV 分别使用 TextWriter 的 twKey 和 twIV 写入两个不同的文件。 ("key" 和 "IV",这两个是没有任何扩展名的文件) TextWriter twKey = new StreamWriter("key"); twKey.Write(ASCIIEncoding.ASCII.GetString(aes.Key)); twKey.Close();并且同样的密钥和文件也使用 TextReader 加载回来。
  • 错误;我一开始也犯了同样的错误。他正在创建两个名为 KeyIV 的文件。
  • 是的,你是对的!我假设密钥已正确加载是错误的:(它实际上是不同的密钥和加载时的 iv...我如何正确地从文件中写入和检索密钥?
  • 用你的答案更新了帖子(你需要 File.ReadAllBytes 和 File.WriteAllBytes)
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    好的,我完美地实现了我想要实现的目标。我的代码中有几个关键故障...... 首先,感谢 SLaks 和 Jipy,我发现“你应该关闭所有打开的流”:)

    我犯的第二个重大错误是试图将密钥和 iv 保存在一个文件中,但实际上保存或加载它不起作用!因此我只有两个 byte[] 来保存密钥和 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); 
    
    
    
        } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      • 2019-06-10
      • 1970-01-01
      • 2015-02-09
      • 2012-08-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多