【发布时间】:2019-11-22 21:32:02
【问题描述】:
我有使用 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 配置并在我的程序中使用它,然后从内存中处理文件。那可能吗?谢谢大家的回答。
PS:不要介意在所有捕获中关闭流。由于某种原因,finally 块不起作用,仍在尝试解决。
//编辑:
这是我的尝试:
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);
问题是我不能在加密流中使用字节数组。即使没有文件流,我还能以某种方式做到这一点吗?
【问题讨论】:
-
使用 MemoryStream 而不是 FileStream。
-
@Dbuggy 然后我可以像处理普通文件一样使用它吗?这就是我的观点,因为直到现在才需要它。从未使用过内存中的对象。如果我做对了:我只是做同样的功能,只是将文件流更改为内存流?但是当我在某个地方调用它时,我怎么知道内存中的对象在哪里?
标签: c# wpf cryptography