Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将文件解密到内存中_C#_Wpf_Cryptography - Fatal编程技术网

C# 将文件解密到内存中

C# 将文件解密到内存中,c#,wpf,cryptography,C#,Wpf,Cryptography,我有一个使用Rijnadel(AES)解密文件的函数。 看起来像这样: public static bool FileDecrypt(string inputFile, string outputFile, string password) { byte[] passwordBytes = Encoding.UTF8.GetBytes(password); byte[] salt = new byte[32]; FileStream f

我有一个使用Rijnadel(AES)解密文件的函数。 看起来像这样:

public static bool FileDecrypt(string inputFile, string outputFile, string password)
    {

        byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
        byte[] salt = new byte[32];

        FileStream fsCrypt = new FileStream(inputFile, FileMode.Open);
        fsCrypt.Read(salt, 0, salt.Length);

        RijndaelManaged AES = new RijndaelManaged();
        AES.KeySize = 256;
        AES.BlockSize = 128;
        var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50000);
        AES.Key = key.GetBytes(AES.KeySize / 8);
        AES.IV = key.GetBytes(AES.BlockSize / 8);
        AES.Padding = PaddingMode.PKCS7;
        AES.Mode = CipherMode.CFB;

        CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateDecryptor(), CryptoStreamMode.Read);

        FileStream fsOut = new FileStream(outputFile, FileMode.Create);

            int read;
            byte[] buffer = new byte[1048576];

            try
            {
                while ((read = cs.Read(buffer, 0, buffer.Length)) > 0)
                {
                    Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { }));
                    fsOut.Write(buffer, 0, read);
                }
            }
            catch (CryptographicException ex_CryptographicException)
            {
                fsOut.Close();
                fsCrypt.Close();
                LogWriter loger = new LogWriter("Cryptography error: " + ex_CryptographicException.ToString());
                return false;
            }
            catch (Exception ex)
            {
                fsOut.Close();
                fsCrypt.Close();
                LogWriter loger = new LogWriter("Exception error: " + ex.ToString());
                return false;
            }

            try
            {
                cs.Close();
            }
            catch (Exception ex)
            {
                fsCrypt.Close();
                fsOut.Close();
                LogWriter loger = new LogWriter("Error when closing Cryptostream. Error: " + ex.ToString());
                return false;
            }
            finally
            {
                fsOut.Close();
                fsCrypt.Close();
            }

    return true;


    }
它解密文件并创建新的解密文件

但我想解密该文件并只将其加载到内存中。主要是xml配置文件,因此我希望使用xmlserializer读取xml配置,并在程序中使用它,然后从内存中处理该文件。可能吗?谢谢你的回答

附言:不要介意关闭所有捕获的溪流。最后,block由于某种原因没有起作用,仍在试图弄清楚这一点

//编辑:

这是我的尝试:

MemoryStream inMemoryCopy = new MemoryStream();

        byte[] salt = new byte[32];
        using (FileStream fs = File.OpenRead(inputfile))
        {
            fs.Read(salt, 0, salt.Length);
            fs.CopyTo(inMemoryCopy);
        }

        byte[] bytesToBeDecrypted = inMemoryCopy.ToArray();
        byte[] passwordBytes = Encoding.UTF8.GetBytes(password);


        RijndaelManaged AES = new RijndaelManaged();
        AES.KeySize = 256;
        AES.BlockSize = 128;
        var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50000);
        AES.Key = key.GetBytes(AES.KeySize / 8);
        AES.IV = key.GetBytes(AES.BlockSize / 8);
        AES.Padding = PaddingMode.PKCS7;
        AES.Mode = CipherMode.CFB;

        CryptoStream cs = new CryptoStream(bytesToBeDecrypted, AES.CreateDecryptor(), CryptoStreamMode.Read);

问题是我不能在加密流中使用字节数组。即使没有filestream,我也可以这样做吗?

您希望使用类似的XmlSerializer从流中获取一些配置对象。不管源流是文件流、网络流还是加密流本身。因此,不需要使用字节缓冲区

注意:以下代码是根据您的代码改编的。我去掉了try-catch,只显示反序列化所需的核心代码

public SomeConfig ReadEncryptedConfiguration(string inputFile, string password)
{
    using (var stream = CreateStream(inputFile, password))
    {
        var ser = new XmlSerializer(typeof(SomeConfig));
        var config = (SomeConfig) ser.Deserialize(stream);
        return config;
    }
}
CreateStream方法将生成前面部分中使用和处理的流。我使用了另一个构造函数来确保在处理加密流时处理底层文件流

public CryptoStream CreateStream(string inputFile, string password)
{
    byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
    byte[] salt = new byte[32];

    FileStream fsCrypt = new FileStream(inputFile, FileMode.Open);
    fsCrypt.Read(salt, 0, salt.Length);

    RijndaelManaged AES = new RijndaelManaged();
    AES.KeySize = 256;
    AES.BlockSize = 128;
    var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50000);
    AES.Key = key.GetBytes(AES.KeySize / 8);
    AES.IV = key.GetBytes(AES.BlockSize / 8);
    AES.Padding = PaddingMode.PKCS7;
    AES.Mode = CipherMode.CFB;

    return new CryptoStream(fsCrypt, AES.CreateDecryptor(), CryptoStreamMode.Read, false);
}

使用MemoryStream而不是文件流。@Dbuggy然后我可以像处理普通文件一样处理它吗?这是我的观点,因为直到现在我才需要它。从未处理过内存中的对象。如果我做对了:我只是做了相同的函数,只是我把文件流改成了内存流?但是当我在某个地方调用它时,我怎么知道对象在内存中的位置呢?我问我需要使用cast,当我想要像这样返回config时?啊,是的,在反序列化时,你需要将它转换为SomeConfig。。我不测试代码。