Thursday, June 21, 2007

Avoid CrpytoStream.Flush()

I needed to attend to some code that was violating an FxCop rule earlier. The code snippet looks something like this:

using (CryptoStream cryptoStream = new CryptoStream(outputStream...))
{
cryptoStream.Write(data, 0, data.Length);
cryptoStream.Close();
encrypted = outputStream.ToArray();
}

The FxCop rule being violated is that we are calling Close and yet Dispose will automatically be called because we are in the context of a using construct.

So I figured I'd just call Flush() instead of Close() - so it would look like this:

using (CryptoStream cryptoStream = new CryptoStream(outputStream...))
{
cryptoStream.Write(data, 0, data.Length);
cryptoStream.Flush();
encrypted = outputStream.ToArray();
}

That turned out to be bad karma and barfed during unit testing with:
System.Security.Cryptography.CryptographicException : Padding is invalid and cannot be removed

I had a look at CrytoStream.Flush() with Reflector and it looks like this:

public override void Flush()
{
}

Hmmmm not much going on there seeing as the documentation says -
"Clears all buffers for this stream and causes any buffered data to be written to the underlying device"

So I checked out the CryptoStream.Dispose() and that makes a call to CryptoStream.FlushFinalBlock() prior to calling CryptoStream.Close(). So I have replaced our call to Flush() with FlushFinalBlock()...makes me wonder whether Flush() was an intentional override that does absolutely nothing whatsoever other than inhibit base class behavior....?

0 comments: