Can a CryptoStream be returned and still have everything right?

If I have a CryptoStream that I want to pass to the user, a naive approach would be

 public Stream GetDecryptedFileStream(string inputFile, byte[] key, byte[] iv) { var fsCrypt = new FileStream(inputFile, FileMode.Open, FileAccess.Read, FileShare.Read); var rmCrypto = new RijndaelManaged(); var transform = rmCrypto.CreateDecryptor(key, iv); var cs = new CryptoStream(fsCrypt, transform, CryptoStreamMode.Read); return cs; } 

I know that when I host CryptoStream , the underlying FileStream will also be used. The problem I am facing is what am I doing with rmCrypto and transform ? RijndaelManaged and ICryptoTransform are one-time classes, but deleting a stream does not destroy these two objects.

What is the right way to deal with this situation?

+6
source share
2 answers

I would think of creating my own class that wraps the stream, and then you can control their removal. Something along these lines (sorry - I do not know the type of transplantation object from my head).

 public CryptoStreamWrapper : Stream, IDisposable { public CryptoStreamWrapper(CryptoStream stream, RijndaelManaged rmCrypto, IDisposable transform) { this.transform = transform; this.rmCrypto = rmCrypto; this.stream = stream; } public void Dispose() { this.transform.Dispose(); this.rmCrypto.Dispose(); this.stream.Dispose(); } } 
+5
source

Ian beat me up to the basic concept ( go upvote him ), but CryptoStream itself is not sealed, so it’s trivial to make a derived class that wraps things that need to be removed.

 /// <summary> /// Creates a class that creates a <see cref="CryptoStream"/> and wraps the disposing action of all the associated objects /// </summary> class ReturnableCryptoStream : CryptoStream { private readonly ICryptoTransform _transform; private readonly IDisposable _algorithm; public ReturnableCryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode) : this(stream, transform, mode, null) { } public ReturnableCryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode, IDisposable algorithm) : base(stream, transform, mode) { _transform = transform; _algorithm = algorithm; } protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) { if (_transform != null) _transform.Dispose(); if (_algorithm != null) _algorithm.Dispose(); } } } 

Used as

 public Stream GetDecryptedFileStream(string inputFile, byte[] key, byte[] iv) { var fsCrypt = new FileStream(inputFile, FileMode.Open, FileAccess.Read, FileShare.Read); var rmCrypto = new RijndaelManaged(); var transform = rmCrypto.CreateDecryptor(key, iv); var cs = new ReturnableCryptoStream(fsCrypt, transform, CryptoStreamMode.Read, rmCrypto); return cs; } 
+5
source

Source: https://habr.com/ru/post/970760/


All Articles