Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / November 2005

Tip: Looking for answers? Try searching our database.

CryptoStream.Dispose closes target stream in 2.0

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Harold Howe - 23 Nov 2005 00:15 GMT
In .net 2.0, the dispose method of CryptoStream calls the Close method
on the destination stream (verified with .NET reflector). In 1.1, it did
not. In my opinion, the 1.1 behavior was preferable. After all, once I
am done decrypting the data, I may want to look at it. Why should I have
to keep the CryptoStream around for that purpose?

Here is an example. This routine works in .net 1.1, but fails in 2.0.

static public string DecryptString(string s, byte[] key, byte[] iv ,
                               SymmetricAlgorithm encryption_algorithm)
{
    using(MemoryStream msout = new MemoryStream())
    {
        byte[] data = Convert.FromBase64String(s);
        using(CryptoStream crypto = new CryptoStream(msout,
                 encryption_algorithm.CreateDecryptor(key,iv),
                 CryptoStreamMode.Write))
        {
            crypto .Write(data,0,data.Length);
            crypto .FlushFinalBlock();
        } // dispose of the cryptostream, we don't need it anymore

        msout.Position = 0;
        data = new byte[msout.Length];
        msout.Read(data, 0, data.Length);

        return System.Text.Encoding.UTF8.GetString(data,0, data.Length);
    }
}

In 2.0, the memorystream is closed when the cryptostream is disposed by
the inner using statement. It is straightforward to refactor this so the
cryptostream lives as long as the memory stream, but that seems
fundamentally wrong from a resource management standpoint.

H^2
Jon Skeet [C# MVP] - 23 Nov 2005 07:25 GMT
> In .net 2.0, the dispose method of CryptoStream calls the Close method
> on the destination stream (verified with .NET reflector). In 1.1, it did
[quoted text clipped - 3 lines]
>
> Here is an example. This routine works in .net 1.1, but fails in 2.0.

<snip>

> In 2.0, the memorystream is closed when the cryptostream is disposed by
> the inner using statement. It is straightforward to refactor this so the
> cryptostream lives as long as the memory stream, but that seems
> fundamentally wrong from a resource management standpoint.

CryptoStream.Dispose was broken in 1.1 in that it didn't close the
CryptoStream itself - IIRC it was actually a no-op.

In this case, however, your code can be improved in simplicity and will
still work in both cases:

static public string DecryptString(string s, byte[] key, byte[] iv ,
                             SymmetricAlgorithm encryption_algorithm)
{
    using(MemoryStream msout = new MemoryStream())
    {
        byte[] data = Convert.FromBase64String(s);
        using(CryptoStream crypto = new CryptoStream(msout,
                 encryption_algorithm.CreateDecryptor(key,iv),
                 CryptoStreamMode.Write))
        {
            crypto .Write(data,0,data.Length);
            crypto .FlushFinalBlock();
        } // dispose of the cryptostream, we don't need it anymore

        data = msout.ToArray();

        return System.Text.Encoding.UTF8.GetString(data,0,
data.Length);
    }
}

If you're dealing with other streams, you could use my
NonClosingStreamWrapper, available from
http://www.pobox.com/~skeet/csharp/miscutils

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Harold Howe - 23 Nov 2005 16:59 GMT
> In this case, however, your code can be improved in simplicity and will
> still work in both cases:

<snip>

Thanks. It looks like the main addition in your code is this:

data = msout.ToArray();

So it is safe to use ToArray after the memory stream is closed? The
entire concept of closing a memory stream is somewhat fuzzy to me.

> If you're dealing with other streams, you could use my
> NonClosingStreamWrapper, available from
> http://www.pobox.com/~skeet/csharp/miscutils

Cool. Thanks.

The correct link is http://www.pobox.com/~skeet/csharp/miscutil for
anyone reading the archive of this.

> CryptoStream.Dispose was broken in 1.1 in that it didn't close the
> CryptoStream itself - IIRC it was actually a no-op.

.net reflector showed that it wasn't quite a no-op, but it doesn't do a
close or flush either.

H^2
Jon Skeet [C# MVP] - 23 Nov 2005 17:49 GMT
> > In this case, however, your code can be improved in simplicity and will
> > still work in both cases:
[quoted text clipped - 7 lines]
> So it is safe to use ToArray after the memory stream is closed? The
> entire concept of closing a memory stream is somewhat fuzzy to me.

Yes, ToArray is fine after closing the stream. From the docs:

<quote>
Note  
This method works when the MemoryStream is closed.
</quote>

> > If you're dealing with other streams, you could use my
> > NonClosingStreamWrapper, available from
[quoted text clipped - 4 lines]
> The correct link is http://www.pobox.com/~skeet/csharp/miscutil for
> anyone reading the archive of this.

Whoops - sorry!

>  > CryptoStream.Dispose was broken in 1.1 in that it didn't close the
>  > CryptoStream itself - IIRC it was actually a no-op.
>
> .net reflector showed that it wasn't quite a no-op, but it doesn't do a
> close or flush either.

The point I noticed when I looked before is that it doesn't flush the
final block (which is part of Close, IIRC).

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too


Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.