从加密流读取到流的末尾 [英] Reading from a cryptostream to the end of the stream

查看:93
本文介绍了从加密流读取到流的末尾的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用下面的代码时遇到了麻烦。我有一个需要加密的临时位置的文件,此功能将加密该数据,然后将其存储在 pathToSave位置。

I'm having some trouble with the code below. I have a file in a temporary location which is in need of encryption, this function encrypts that data which is then stored at the "pathToSave" location.

检查是似乎不能正确地处理整个文件-输出中缺少一些位,我怀疑它与while循环没有在整个流中运行有关。

On inspection is does not seem to be handling the whole file properly - There are bits missing from my output and I suspect it has something to do with the while loop not running through the whole stream.

顺便说一句,如果我尝试在while循环之后调用CryptStrm.Close(),则会收到异常。这意味着,如果我尝试解密文件,则会得到文件已在使用中的错误!

As an aside, if I try and call CryptStrm.Close() after the while loop I receive an exception. This means that if I attempt to decrypt the file, I get a file already in use error!

尝试了所有常规方法,我在这里也遇到了类似的问题,任何帮助都将是非常有用的。

Tried all the usual and Ive looked on here at similar issues, any help would be great.

谢谢

public void EncryptFile(String tempPath, String pathToSave)
    {
        try
        {
            FileStream InputFile = new FileStream(tempPath, FileMode.Open, FileAccess.Read);
            FileStream OutputFile = new FileStream(pathToSave, FileMode.Create, FileAccess.Write);

            RijndaelManaged RijCrypto = new RijndaelManaged();

            //Key
            byte[] Key = new byte[32] { ... };

            //Initialisation Vector
            byte[] IV = new byte[32] { ... };

            RijCrypto.Padding = PaddingMode.None;
            RijCrypto.KeySize = 256;
            RijCrypto.BlockSize = 256;
            RijCrypto.Key = Key;
            RijCrypto.IV = IV;

            ICryptoTransform Encryptor = RijCrypto.CreateEncryptor(Key, IV);

            CryptoStream CryptStrm = new CryptoStream(OutputFile, Encryptor, CryptoStreamMode.Write);

            int data;
            while (-1 != (data = InputFile.ReadByte()))
            {
                CryptStrm.WriteByte((byte)data);
            }
        }
        catch (Exception EncEx)
        {
            throw new Exception("Encoding Error: " + EncEx.Message);
        }
    }

编辑:

我已经假设我的问题与加密有关。我的Decrypt可能是罪魁祸首

I've made the assumption that my problem is with Encryption. My Decrypt might be the culprit

        public String DecryptFile(String encryptedFilePath)
    {
        FileStream InputFile = new FileStream(encryptedFilePath, FileMode.Open, FileAccess.Read);

        RijndaelManaged RijCrypto = new RijndaelManaged();

        //Key
        byte[] Key = new byte[32] { ... };

        //Initialisation Vector
        byte[] IV = new byte[32] { ... };

        RijCrypto.Padding = PaddingMode.None;
        RijCrypto.KeySize = 256;
        RijCrypto.BlockSize = 256;
        RijCrypto.Key = Key;
        RijCrypto.IV = IV;

        ICryptoTransform Decryptor = RijCrypto.CreateDecryptor(Key, IV);

        CryptoStream CryptStrm = new CryptoStream(InputFile, Decryptor, CryptoStreamMode.Read);

        String OutputFilePath = Path.GetTempPath() + "myfile.name";
        StreamWriter OutputFile = new StreamWriter(OutputFilePath);

        OutputFile.Write(new StreamReader(CryptStrm).ReadToEnd());

        CryptStrm.Close();
        OutputFile.Close();

        return OutputFilePath;
    }


推荐答案

嗯,有几件事

1。您设置的IV的大小太大。如果密钥大小为256,则Rijndael的IV为16字节。如果尝试将密钥设置为更多的字节,则会出现异常。 IV大小应设置为块大小 / 8 参见MSDN ,因此您拥有的IV大小是正确的。

1. Your setting the size of the IV too large. If you have a key size of 256, the IV for Rijndael is 16 bytes. If you try to set the key with more bytes than that you will get an exception. IV size should be set to Block size / 8 see MSDN so the IV size you have is correct.


  1. 您的填充模式为无。除非您的数据正好是正确的块大小,否则您将遇到问题。您可能想要选择一种填充模式。

  2. 加密时,通常需要在完成对加密流的写操作后调用FlushFInalBlock,以确保将所有数据都写入流。 / li>
  1. You have a padding mode of None. Unless your data is exactly the correct block size, then you are going to have problems. You probably want to pick a padding mode.
  2. You typically need to call FlushFInalBlock when done writing to the crypto stream when you are encrypting to ensure all of the data is written to the stream.

我正在使用内存流发布一些示例代码,以显示加密和解密。

I am posting some sample code using memory streams to show the encrypting and decrypting.

var tempData = "This is the text to encrypt. It's not much, but it's all there is.";

using (var rijCrypto = new RijndaelManaged())
{
    byte[] encryptedData;
    rijCrypto.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
    rijCrypto.KeySize = 256;

    using (var input = new MemoryStream(Encoding.Unicode.GetBytes(tempData)))
    using (var output = new MemoryStream())
    {
        var encryptor = rijCrypto.CreateEncryptor();

        using (var cryptStream = new CryptoStream(output, encryptor, CryptoStreamMode.Write))
        {
            var buffer = new byte[1024];
            var read = input.Read(buffer, 0, buffer.Length);
            while (read > 0)
            {
                cryptStream.Write(buffer, 0, read);
                read = input.Read(buffer, 0, buffer.Length);
            }
            cryptStream.FlushFinalBlock();
            encryptedData = output.ToArray();
        }
    }

    using (var input = new MemoryStream(encryptedData))
    using (var output = new MemoryStream())
    {
        var decryptor = rijCrypto.CreateDecryptor();
        using (var cryptStream = new CryptoStream(input, decryptor, CryptoStreamMode.Read))
        {
            var buffer = new byte[1024];
            var read = cryptStream.Read(buffer, 0, buffer.Length);
            while (read > 0)
            {
                 output.Write(buffer, 0, read);
                 read = cryptStream.Read(buffer, 0, buffer.Length);
            }
            cryptStream.Flush();
            var result = Encoding.Unicode.GetString(output.ToArray());
        }
    }
}

这篇关于从加密流读取到流的末尾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆