3

Docs never really mention why CryptoStream should be used instead of TransformBlock and TransformFinalBlock other than that it calls whichever is needed automatically.

Thus, why would one use the code in this answer (https://stackoverflow.com/a/2006922/7343355) instead of this:

using (var encryptor = aes.CreateEncryptor())
{
    result = encryptor.TransformFinalBlock(data, 0, data.Length); // Data length is greater than the blocksize
}

Even though TransformFinalBlock should be used after TransformBlockand only on the last block, somehow this code passed all the unit tests and always gives me the correct result. Are there any cases where this could fail? Does this have something to do with me using ECB cipher mode to test this and would fail under other modes?

karolyzz
  • 480
  • 4
  • 28

1 Answers1

4

The reason why CryptoStream is generally preferred is that it's more generally applicable. It's used for symmetric encryption which can often involve large amounts of data. For practical reasons, such as limiting memory usage, it may not be practical to have the entire thing to be encrypted and the encrypted output all in memory at the same time.

As such, you'll likely already be working with streams, such as NetworkStream or FileStream. CryptoStream naturally composes well with these other streams so that you'll often end up building a pipeline (or possibly two with CopyTo or CopyToAsync bridging the gap between the "read" side and the "write" side).

If you're in a position where the entirety of what is to be encrypted is small and already in memory, and so you'll also be able to cope with the whole encrypted output being in memory, then sure, you can just use TransformFinalBlock instead. And you'll save yourself a few object allocations (but we've already said memory usage isn't a problem if we're here...), at the expense of now having to write your crypto code in one of two completely different ways depending on each use case.


Meta bit

Unfortunately, the toy examples we get in questions (either "something like..." or actual MCVEs) will look like they fit the second case. But most people answering such questions will assume that the code will need to cope with situations more akin to the first, and so they'll still offer CryptoStream based solutions even if the TransformFinalBlock one would work for the code in the question.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
  • 1
    So if we have entire data...then we can use TransformFinalBlock() directly instead of CryptoStream. – jiten Sep 26 '19 at 06:08
  • 1
    @Damien_The_Unbeliever So...are you saying, `TransformBlock` and `TransformFinalBlock` are array-based for working with small amounts of data and `CryptoStream` is stream-based for working with large data in chunks? – Suncat2000 Jul 06 '21 at 17:10