我发现自己重复了这段代码
using (var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read)
{
using (var aes = AesCryptoServiceProvider() { Key = ... }
{
// Read the IV at the beginning of the filestream
using (var cryptoStream = new CryptoStream(fileStream, aes.CreateDecryptor(), CryptoStreamMode.Read)
{
// Actual code only using cryptoStream
}
}
}
和
using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write)
{
using (var aes = AesCryptoServiceProvider() { Key = ... }
{
// Write the IV at the beginning of the filestream
using (var cryptoStream = new CryptoStream(fileStream, aes.CreateDecryptor(), CryptoStreamMode.Write)
{
// Actual code only using cryptoStream
}
}
}
我问自己,是否可以用这样的东西替换它
using (var cryptoStream = new MyDecryptionStream(path))
{
// Actual code
}
实际代码可能非常不同。它可以是必须保存的图像或xml序列化。
我尝试实现自己的Stream类,将所有方法强制转换为私有属性CryptoStream。但这没有成功。它始终打破了对手,在那里我试着在开始时阅读IV。
答案 0 :(得分:1)
这是您正在尝试做的非常粗略的示例。有很多地方可以改进,但这是一个可以建立的工作样本。
首先,我们创建一个实现IDisposable
的类。这允许我们在using
语句中使用此类。这个类将实例化我们需要的其他三个对象,并自行处理它们。
class MyCryptoStream : IDisposable
{
private FileStream fileStream = null;
private AesCryptoServiceProvider aes = null;
public CryptoStream cryptoStream = null;
public enum Mode
{
Write,
Read
}
public MyCryptoStream(string filepath, Mode mode, byte[] key, byte[] iv = null)
{
if(mode == Mode.Write)
{
fileStream = new FileStream(filepath, FileMode.Open, FileAccess.Write);
fileStream.Write(iv, 0, 16);
aes = new AesCryptoServiceProvider() { Key = key, IV = iv };
cryptoStream = new CryptoStream(fileStream, aes.CreateEncryptor(), CryptoStreamMode.Write);
}
else
{
iv = new byte[16];
fileStream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
fileStream.Read(iv, 0, 16);
aes = new AesCryptoServiceProvider() { Key = key, IV = iv };
cryptoStream = new CryptoStream(fileStream, aes.CreateDecryptor(), CryptoStreamMode.Read);
}
}
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
if (cryptoStream != null)
{
cryptoStream.Dispose();
}
if (aes != null)
{
aes.Dispose();
}
if (fileStream != null)
{
fileStream.Dispose();
}
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
disposedValue = true;
}
}
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
// ~UsingReduction() {
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
// Dispose(false);
// }
// This code added to correctly implement the disposable pattern.
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}
#endregion
}
现在,我们可以像这样使用这个类:
string path = "..\\..\\test.txt";
byte[] key = null;
byte[] iv = null;
using (AesCryptoServiceProvider myAes = new AesCryptoServiceProvider())
{
key = myAes.Key;
iv = myAes.IV;
}
using (MyCryptoStream ur = new MyCryptoStream(path, MyCryptoStream.Mode.Write, key, iv))
{
using (StreamWriter sw = new StreamWriter(ur.cryptoStream))
{
sw.Write("Test string");
}
}
string text = string.Empty;
using (MyCryptoStream ur = new MyCryptoStream(path, MyCryptoStream.Mode.Read, key))
{
using (StreamReader sr = new StreamReader(ur.cryptoStream))
{
text = sr.ReadToEnd();
}
}
如果运行此示例,您可以看到它使用"Test string"
将cryptostream
写入文件,然后从该文件中读取相同的文本。检查text
的值,我们可以看到它仍为"Test string"
,表示该过程已成功。
答案 1 :(得分:1)
辅助功能怎么样?
public static TResult ReadFileUsingCrypto<TResult>(string path, KeyThing key, Func<CryptoStream, TResult> use)
{
using (var fileStream = new FileStream(path, FileMode.Open, FileAccesa.Read))
using (var aes = new AesCryptoServiceProvider(){...}))
using (var cryptoStream = new CryptoStream(fileStream, aes.CreateDecryptor(), CryptoStreamMode.Read))
{
return use(cryptoStream);
}
}
然后
var result = ReadFileUsingCrypto(“myFile”, key, crypto => <use crypto here and return result>);