[Mono-bugs] [Bug 345510] CryptoStream ignores the ICryptoTransform. CanTransformMultipleBlocks property when reading

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Mon Dec 3 15:25:24 EST 2007


https://bugzilla.novell.com/show_bug.cgi?id=345510

User lordhabbit at gmail.com added comment
https://bugzilla.novell.com/show_bug.cgi?id=345510#c3


Javier Martin <lordhabbit at gmail.com> changed:

           What    |Removed                                         |Added
----------------------------------------------------------------------------
             Status|NEEDINFO                                        |ASSIGNED
      Info Provider|lordhabbit at gmail.com                            |




--- Comment #3 from Javier Martin <lordhabbit at gmail.com>  2007-12-03 13:25:24 MST ---
As I made pretty clear, the bug is in the CS.Read method, not in CS.Write which
you use in your code example. I know there are other ways I can go -
ComputeHash is a good one for one algorithm, but I'm chaining them. Also, I'd
rather not use CS.Write in order to read data from a file: seems too much of a
hack to me.

This is a sample of the code I'm using, modified to remove some Trace output
and  instances of classes from my project:

        static Stack<byte[]> HashFile(string fileName, HashAlgorithm[]
algorithms)
        {
            if (fileName != null && algorithms != null &&
File.Exists(fileName))
            {
                Stack<byte[]> output = new Stack<byte[]>;

                foreach (HashAlgorithm alg in algorithms)
                    alg.Initialize();

                using (FileStream source = File.OpenRead(fileName))
                {
                    // Channel all hash CryptoStreams: the output of a hash
                    // ICryptoTransform is the same as its input, while the
                    // result is saved in the HashAlgorithm instance.
                    Stack<Stream> pipes = new Stack<Stream>(algorithms.Length +
1);
                    pipes.Push(source);
                    foreach (HashAlgorithm alg in algorithms)
                        pipes.Push(new CryptoStream(pipes.Peek(), alg,
CryptoStreamMode.Read));
                    Stream lastPipe = pipes.Peek();
                    // Set up a temporary buffer to read and hash just a chunk
                    // at a time instead of reading a possibly very large file
                    // to memory and then hashing.                   
                    byte[] readBuffer = new byte[READBUFFER_SIZE];
                    // The real hashing is done here - on reading, data passes
                    // through all set CryptoStreams. For all that matters, the
                    // loop could well be empty
                    while (0 < lastPipe.Read(readBuffer, 0, READBUFFER_SIZE)) {
}
                    lastPipe.Close();   // Closes all underlying Streams
                }

                // Get the hash values and return it
                foreach (HashAlgorithm alg in algorithms)
                    output.Push(alg.Hash);
                return output;
            }
            else return null;
        }

As you can see, I'm using hash chaining, so resorting to CS.Write would mean
jumping through so many hoops that it'd probably not be useful. Besides, this
code works correctly and efficiently in .NET 2, while in Mono it takes the time
I stated in the first post (about 2 secs) to hash a 3 MB file (that's 1/30 of
your test file).


-- 
Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.


More information about the mono-bugs mailing list