HOW? Capture output stream as byte array

L

Lee Gillie

I am using Cryptography. You can encrypt or decrypt by providing an
output stream as a parameter to the CryptoStream constructor. But I
need byte arrays, as I am encrypting on the fly to a socket, and need
to manage all socket traffic.

My thought was a stateful call to my own Encrypt and Decrypt routines.
That I would pass a MemoryStream to the CryptoStream constructor. But
it appears that for each write CryptoStream does to my memory stream,
there is no way for me to get the bytes out of the MemoryStream and
and reset the MemoryStream content, so that its byte content does not
continue to grow. The files being encrypted, for example, might be as
large as 100MB. I could encrypt entirely to YATDF (yet another
temporary disk file), and the pass that to the socket. But if there
is a way, I would like to avoid a disk file.

Maybe MemoryStream is NOT the right object, because I don't see how to
do the above. Is there some other stream object, or perhaps, a way to
do what I want with MemoryStream?

TIA - best regards, Lee Gillie
 
J

Jon Skeet [C# MVP]

Lee Gillie said:
I am using Cryptography. You can encrypt or decrypt by providing an
output stream as a parameter to the CryptoStream constructor. But I
need byte arrays, as I am encrypting on the fly to a socket, and need
to manage all socket traffic.

My thought was a stateful call to my own Encrypt and Decrypt routines.
That I would pass a MemoryStream to the CryptoStream constructor. But
it appears that for each write CryptoStream does to my memory stream,
there is no way for me to get the bytes out of the MemoryStream and
and reset the MemoryStream content, so that its byte content does not
continue to grow. The files being encrypted, for example, might be as
large as 100MB. I could encrypt entirely to YATDF (yet another
temporary disk file), and the pass that to the socket. But if there
is a way, I would like to avoid a disk file.

Maybe MemoryStream is NOT the right object, because I don't see how to
do the above. Is there some other stream object, or perhaps, a way to
do what I want with MemoryStream?

You could always just write your own Stream implementation - that
wouldn't be particularly hard, especially if you're just handing off
whatever is written.
 
L

Lee Gillie

Yes, that's what I did. I did not realize it was so trivial to derive
from Stream. The one awkward part was that my implementation of
Write() was called one additional time when the cryptography stream
was closed. But it is coded and tested, and works well.

Thanks - Lee
 
J

Jay B. Harlow [MVP - Outlook]

Lee,
In addition to the other comments.

If you are writing to a socket, why not just pass the NetworkStream itself
to the CryptoStream class?

You can use MemoryStream.GetBuffer & MemoryStream.ToArray to get the bytes
out.

I believe you can use MemoryStream.SetLength to reset the memory stream.
(based on reading the help, I have not tried it). However I would simply use
a new MemoryStream object each time I needed one.

I'm not so certain you need a MemoryStream, as I would simply pass the
NetworkStream itself to the CryptoStream.

Hope this helps
Jay
 
R

Rob Teixeira [MVP]

I was going to say that MemoryStream.GetArray() will return the bytes, but
Jay beat me to it.
An alternate option is to just pass a NetworkStream to the CryptoStream
constructor instead of a memory stream. That way, the crypto stream writes
directly to the socket. If you are using the TCPClient, you can get the
network stream from the GetStream method.

-Rob Teixeira [MVP]
 
R

Richard Grimes [MVP]

Lee said:
Yes, that's what I did. I did not realize it was so trivial to derive
from Stream. The one awkward part was that my implementation of
Write() was called one additional time when the cryptography stream
was closed. But it is coded and tested, and works well.

That's because the crypto routines are block routines and hence they are
flushed after they are finished.

Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top