0

all!

I am using the CryptoStream class, testing with a memoryStream. In the future, we will be using network data, so the stream will be read only and CanSeek = false.

The test data is about 750 bytes. The first 250 bytes are a header and are read OK. The second 250 bytes is the 'real' data. The third 250 bytes are a trailer that contains validation values e.g. hmac for the stream.

Here is a clip of the code. I am at the position 250 and ask CryptoStream.Read to fetch 250 bytes. 250 bytes are returned, but the input position is now at the end of the stream. Any ideas?

byteCount = cs.Read(outputBuffer, 0, bytesToRead)



00005001 inStream.Position = 256
00005002 inStream.Length   = 768
00005003 bytesToRead       = 256
00005004 bytesLeft         = 256
00005010 Invoking cs.Read(outputBuffer, 0, bytesToRead)
00005011 inStream.Position = 768
00005012 inStream.Length   = 768
00005013 bytesToRead       = 256
00005014 bytesLeft         = 0
00005015 byteCount         = 256

Thanks in advance for your help!

Pete
  • 45
  • 1
  • 2
  • 8
  • I strongly suspect that CryptoStream is "overreading" in order to buffer data for the sake of efficiency. If you know how much data is *actually* encrypted data, I'd put that into a separate stream. – Jon Skeet Nov 22 '17 at 16:20
  • The number of bytes read from the `MemoryStream` is different with the number of bytes read from the `CryptoStream`. `CryptoStream` transform input and output, so these numbers may not match. It might also overread if data is in an encrypted block. You should not rely on the underlying stream. That's the whole idea of this class. What do you want to achieve with knowing the pointer position? – Soroush Falahati Nov 22 '17 at 16:33
  • @JonSkeet Thanks for taking a look. It does seem to be over-reading. The issue with this application is that we don't know how much data will be coming in the stream. – Pete Nov 22 '17 at 17:56
  • Do you control the protocol? When a stream logically contains several separate "chunks" of data, it's very, very useful to prefix each chunk with the length. – Jon Skeet Nov 22 '17 at 18:00
  • @SoroushFalahati Thanks for your feedback. I need to process the final N bytes as a trailer, which is not encrypted. So when I read from the CryptoStream, I am telling it to read x-n bytes. I can then use the base stream to process the final trailing block of data. The trailer block contains hmac values to verify the decryption. In this case, we can't use Seek or Position. – Pete Nov 22 '17 at 18:01
  • Well, you should create a protocol over your data chunks; especially if you want to use network stream. I suggest leaving 4 bytes at the start of the stream to read the number of bytes that need to be decrypted, and then leave some fixed number of bytes after for metadata. This is the simplest protocol that can think of now. There is no guarantee that you receive TCP chunk in the exact size you have sent them. So you eventually need this. – Soroush Falahati Nov 22 '17 at 18:17

0 Answers0