在我的一些项目中,我一直在使用一对可靠的数据加密/解密方法(加密方法粘贴在下面)。但是我一直对CA2202这个关于memoryStream对象的警告(“不要多次放置对象”)感到困惑。我相信我会以适当的方式处理此问题,但是只要在Visual Studio中运行分析,我仍然会收到警告。它从未在生产代码中引发异常,但我仍然想一劳永逸地摆脱警告。那可能吗?还是我应该忽略它?预先感谢。
public static string Encrypt(string clearText, string passPhrase, string saltValue)
{
byte[] clearTextBytes = Encoding.UTF8.GetBytes(clearText);
byte[] saltValueBytes = Encoding.UTF8.GetBytes(saltValue);
Rfc2898DeriveBytes passPhraseDerviedBytes = new Rfc2898DeriveBytes(passPhrase, saltValueBytes);
byte[] keyBytes = passPhraseDerviedBytes.GetBytes(32);
byte[] initVectorBytes = passPhraseDerviedBytes.GetBytes(16);
RijndaelManaged symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC };
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
byte[] cipherTextBytes = null;
MemoryStream memoryStream = null;
try
{
memoryStream = new MemoryStream();
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(clearTextBytes, 0, clearTextBytes.Length);
cryptoStream.FlushFinalBlock();
cipherTextBytes = memoryStream.ToArray();
}
}
finally
{
if (memoryStream != null)
{
memoryStream.Dispose();
}
}
return Convert.ToBase64String(cipherTextBytes);
}
答案 0 :(得分:1)
这是因为CryptoStream
关闭了memoryStream
您正在使用构造函数
public CryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode)
: this(stream, transform, mode, false) {
}
调用
public CryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode, bool leaveOpen) {
_stream = stream;
_leaveOpen = leaveOpen;
//...
}
_leaveOpen
和_stream
稍后在Dispose
protected override void Dispose(bool disposing) {
try {
if (!_leaveOpen) {
_stream.Close();
}
//...
}
}
您可以删除memoryStream.Dispose();
,或将true
作为参数传递给CryptoStream
构造函数
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write, true)) { }
答案 1 :(得分:1)
问题在于对CryptoStream.Dispose
的调用可以调用放置在给定的流上:
protected override void Dispose(bool disposing) { try { if (disposing) { if (!_finalBlockTransformed) { FlushFinalBlock(); } if (!_leaveOpen) { _stream.Close(); } } } ... }
如果您使用带有4个参数的构造函数:
CryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode, bool leaveOpen)
最后一个参数确定流是否已关闭。默认情况下,依次调用Close()
也会调用Dispose
:
public virtual void Close() { /* These are correct, but we'd have to fix PipeStream & NetworkStream very carefully. Contract.Ensures(CanRead == false); Contract.Ensures(CanWrite == false); Contract.Ensures(CanSeek == false); */ Dispose(true); GC.SuppressFinalize(this); }
因此,似乎检查无法正确确定特定的Stream实现是否将被Dispose,而回过头来以为会是这种情况。
但是请注意,在大多数情况下,对MemoryStream
进行两次,一次或零次处理并不重要。