1
votes

I'm trying to create a stream that receive an underlying stream in the constructor, and automatically encrypt data when we read it. The goal is that when we read from the EncryptingStream : - it read the underlying stream - it encrypt the bytes read from the underlying stream - it returns the encrypted bytes

My current code looks like this:

public class EncryptingStream : BaseCryptographicStream
{
    protected CryptoStream _current;
    protected ICryptoTransform _transform;
    protected Stream _underlyingStream;

    #region CTor
    public EncryptingStream(Stream source, string encryptionKey)
        : base(target)
    {
        this._underlyingStream = source;
        this.Initialize(encryptionKey);
    }
    #endregion


    protected void Initialize(string encryptionKey)
    {
        var input = CryptoTools.GenerateAlgorithmInputs(encryptionKey);

        RijndaelManaged rijndael = new RijndaelManaged();
        rijndael.Mode = CipherMode.CBC;
        rijndael.Key = input[0];
        rijndael.IV = input[1];

        this._transform = rijndael.CreateEncryptor();
        this._current = new CryptoStream(this._underlyingStream, this._transform, CryptoStreamMode.Write);
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        ??
    }
}

Notice: BaseCryptographicStream inherit Stream and implement Stream abstract members not implemented by the class above.

My problem is that I'm stuck implementing the Read method.
I can't use the CryptoStream as this stream write to an output stream.
I think I've to use the ICryptoTransform object but I've no idea on how to read correctly. Problem here is the mismatch between the length of encrypted and unencrypted data. so the buffer read from the underlying stream will have a different size than the buffer given to EncryptingStream.

Does someone know it this kind of stream is possible, and any idea on how to do it ?

Update 1: The problem I try to solve here is for WCF streaming. I stream (big) files to WCF and don't want to put the whole file in memory. Using CryptoStream means that I must use a intermediate MemoryStream to encrypt the content, which mean the whole file will be in memory

1
Have you considered using a standard CryptoStream? See msdn.microsoft.com/en-us/library/…Kris Vandermotten
Yes, the CryptoStream write to an output stream, which is the opposite of what I try to do here. The goal is to stream big files via network and not put all in memory before encryption.Fabske
I've edited my question to add more information on the contextFabske
To use a CryptoStream for reading, just construct it with CryptoStreamMode.Read. See msdn.microsoft.com/en-us/library/… and msdn.microsoft.com/en-us/library/…Kris Vandermotten
Every sample I've found on the net use the write for encrypting, and the read for decrypting. Do you means we can use read + encrypting ?Fabske

1 Answers

2
votes

Instead of rolling your own, just use the standard CryptoStream class. To enable reading from it, use CryptoStreamMode.Read in the constructor call.