1

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

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();引发加密异常“填充无效且无法删除”。

whilerichTextBox1.LoadFile(fx.BaseStream, RichTextBoxStreamType.RichText);抛出NotSupportedException “Stream 不支持搜索”。

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

4

3 回答 3

1

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

于 2010-04-08T14:12:20.203 回答
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();
                }
            }
        }

    }

有用。

于 2010-04-08T14:15:26.397 回答
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); 



    } 
于 2010-04-08T14:58:14.180 回答