C# 将文件解密到内存中
我有一个使用Rijnadel(AES)解密文件的函数。 看起来像这样: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
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。。我不测试代码。