0

I've seen a bunch of these questions on here, but none of the answers have been able to resolve my problem. I wrote a Socket to sit on one of our servers, and using another program to talk with that Socket in order to get an encryption key for decrypting sensitive data. Below is my code.

Socket Server:

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Security.Cryptography;

namespace Netgen_Encryption_Socket
{
    class Program
    {
        private static IPAddress ip = IPAddress.Parse("127.0.0.1");
        private static string encryptionKey = "2387429837498279832";
        private static byte[] IV = new byte[] { 23, 243, 29, 26, 78, 67, 23, 62, 81, 93, 12, 205, 217, 10, 216, 13 };
        private static byte[] salt = new byte[] { 21, 10, 3, 26, 10, 3, 1, 49, 55, 171, 1, 51, 75, 16, 27, 14, 23, 29, 70, 16, 55, 18, 12, 2, 4, 29, 77, 52, 5, 44, 127, 164 };
        private static string masterPassword = "SecretPassword";
        private static bool connectionAccepted = true;

        static void Main(string[] args) => Listen();

        static void Listen()
        {
            TcpListener serverSocket = new TcpListener(IPAddress.Any, 9843);
            TcpClient clientSocket = default(TcpClient);

            int requestCount = 0;

            serverSocket.Start();
            clientSocket = serverSocket.AcceptTcpClient();

            if (((IPEndPoint)clientSocket.Client.RemoteEndPoint).Address.ToString() == ip.ToString())
            {
                SendMessage(clientSocket, serverSocket, $"Accepted Connection from {((IPEndPoint)clientSocket.Client.RemoteEndPoint).Address}");
                connectionAccepted = true;
            }
            else
            {
                SendMessage(clientSocket, serverSocket, $"Rejected Connection from {((IPEndPoint)clientSocket.Client.RemoteEndPoint).Address}");
                Restart(clientSocket, serverSocket);
            }

            while (connectionAccepted)
            {
                try
                {
                    requestCount += 1;

                    if (requestCount >= 4)
                        Restart(clientSocket, serverSocket);

                    string data = GetMessage(clientSocket, serverSocket);

                    if (data == masterPassword)
                    {
                        SendMessage(clientSocket, serverSocket, encryptionKey);
                    }
                    else
                    {
                        SendMessage(clientSocket, serverSocket, $"Invalid master password. {3 - requestCount} attempts remaining!");

                        if (3 - requestCount <= 0)
                            SendMessage(clientSocket, serverSocket, Environment.NewLine +  $"Too many incorrect attempts. Connection terminated!");
                    }
                }
                catch
                {
                    Restart(clientSocket, serverSocket);
                }
            }

            Stop(clientSocket, serverSocket);
        }

        static void Restart(TcpClient client, TcpListener listener)
        {
            client.Close();
            listener.Stop();

            Listen();
        }

        static void Stop(TcpClient client, TcpListener listener)
        {
            client.Close();
            listener.Stop();
        }

        static string GetMessage(TcpClient client, TcpListener listener)
        {
            NetworkStream networkStream = client.GetStream();

            byte[] bytesFrom = new byte[client.ReceiveBufferSize];
            networkStream.Read(bytesFrom, 0, (int)client.ReceiveBufferSize);

            string data = Decrypt(bytesFrom);
            data = data.Substring(0, data.IndexOf("$"));

            return data;
        }

        static void SendMessage(TcpClient client, TcpListener listener, string message)
        {
            NetworkStream networkStream = client.GetStream();

            byte[] sendBytes = Encrypt(message);
            networkStream.Write(sendBytes, 0, sendBytes.Length);
            networkStream.Flush();
        }

        static byte[] Encrypt(string stringToEncrypt)
        {
            byte[] encryptedBytes;

            using(Aes AES = Aes.Create())
            {
                AES.Key = salt;
                AES.IV = IV;

                AES.Mode = CipherMode.CBC;
                AES.Padding = PaddingMode.PKCS7;

                var encryptor = AES.CreateEncryptor(AES.Key, AES.IV);

                using(MemoryStream ms = new MemoryStream())
                {
                    using(CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                    {
                        using(StreamWriter sw = new StreamWriter(cs))
                        {
                            sw.Write(stringToEncrypt);
                        }

                        encryptedBytes = ms.ToArray();

                        if (!cs.HasFlushedFinalBlock)
                            cs.FlushFinalBlock();
                    }
                }
            }

            var combined = new byte[IV.Length + encryptedBytes.Length];
            Array.Copy(IV, 0, combined, 0, IV.Length);
            Array.Copy(encryptedBytes, 0, combined, IV.Length, encryptedBytes.Length);

            return combined;
        }

        static string Decrypt(byte[] bytesToDecrypt)
        {
            string decryptedString = null;

            using(Aes AES = Aes.Create())
            {
                AES.Key = salt;

                byte[] cipherText = new byte[bytesToDecrypt.Length - IV.Length];

                Array.Copy(bytesToDecrypt, IV, IV.Length);
                Array.Copy(bytesToDecrypt, IV.Length, cipherText, 0, cipherText.Length);

                AES.IV = IV;

                AES.Mode = CipherMode.CBC;
                AES.Padding = PaddingMode.PKCS7;

                var decryptor = AES.CreateDecryptor(AES.Key, AES.IV);

                using(MemoryStream ms = new MemoryStream(cipherText))
                {
                    using(CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                    {
                        using(StreamReader sr = new StreamReader(cs))
                        {
                            decryptedString = sr.ReadToEnd();
                        }
                    }
                }
            }

            return decryptedString;
        }
    }
}

Socket Client:

using System;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Security.Cryptography;

namespace Client_Socket_Tester
{
    public partial class Form1 : Form
    {
        TcpClient clientSocket = new TcpClient();
        private static byte[] IV = new byte[] { 23, 243, 29, 26, 78, 67, 23, 62, 81, 93, 12, 205, 217, 10, 216, 13 };
        private static byte[] salt = new byte[] { 21, 10, 3, 26, 10, 3, 1, 49, 55, 171, 1, 51, 75, 16, 27, 14, 23, 29, 70, 16, 55, 18, 12, 2, 4, 29, 77, 52, 5, 44, 127, 164 };

        public Form1() => InitializeComponent();

        private void Form1_Load(object sender, EventArgs ev)
        {
            try
            {
                clientSocket.Connect(IPAddress.Parse("127.0.0.1"), 9843);
                AppendClientMessage(" >> Connection established");
            }
            catch (Exception e)
            {
                AppendClientMessage($" >> Client Error: {e.Message}");
            }
        }

        private void AppendClientMessage(string msg)
        {
            richTextBox1.Text += Environment.NewLine + msg;
        }

        private void SendMessage(string msg)
        {
            try
            {
                byte[] outStream = Encrypt($"{msg}$");

                NetworkStream serverStream = clientSocket.GetStream();
                serverStream.Write(outStream, 0, outStream.Length);
                serverStream.Flush();

                byte[] inStream = new byte[clientSocket.ReceiveBufferSize];
                serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize);

                string returnData = Decrypt(inStream);
                AppendClientMessage(returnData);
                richTextBox2.Text = "";
                richTextBox2.Focus();
            }
            catch (Exception e)
            {
                AppendClientMessage($" >> Client Error: {e.Message}");
            }
        }

        private void button1_Click(object sender, EventArgs ev)
        {
            try
            {
                SendMessage(richTextBox2.Text);
            }
            catch (Exception e)
            {
                AppendClientMessage($" >> Client Error: {e.Message}");
            }
        }

        static byte[] Encrypt(string stringToEncrypt)
        {
            byte[] encryptedBytes;

            using (Aes AES = Aes.Create())
            {
                AES.Key = salt;
                AES.IV = IV;

                AES.Mode = CipherMode.CBC;
                AES.Padding = PaddingMode.PKCS7;

                var encryptor = AES.CreateEncryptor(AES.Key, AES.IV);

                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter sw = new StreamWriter(cs))
                        {
                            sw.Write(stringToEncrypt);
                        }

                        encryptedBytes = ms.ToArray();

                        if (!cs.HasFlushedFinalBlock)
                            cs.FlushFinalBlock();
                    }
                }
            }

            var combined = new byte[IV.Length + encryptedBytes.Length];
            Array.Copy(IV, 0, combined, 0, IV.Length);
            Array.Copy(encryptedBytes, 0, combined, IV.Length, encryptedBytes.Length);

            return combined;
        }

        static string Decrypt(byte[] bytesToDecrypt)
        {
            string decryptedString = null;

            using (Aes AES = Aes.Create())
            {
                AES.Key = salt;

                byte[] cipherText = new byte[bytesToDecrypt.Length - IV.Length];

                Array.Copy(bytesToDecrypt, IV, IV.Length);
                Array.Copy(bytesToDecrypt, IV.Length, cipherText, 0, cipherText.Length);

                AES.IV = IV;

                AES.Mode = CipherMode.CBC;
                AES.Padding = PaddingMode.PKCS7;

                var decryptor = AES.CreateDecryptor(AES.Key, AES.IV);

                using (MemoryStream ms = new MemoryStream(cipherText))
                {
                    using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader sr = new StreamReader(cs))
                        {
                            decryptedString = sr.ReadToEnd();
                        }
                    }
                }
            }

            return decryptedString;
        }
    }
}

I have tried most of the suggestions in other, similar posts. Including changing the padding mode, and/or converting to Base64. The end results is always either the encoding is messed up and spits out a series of random characters, or it gives me a "Padding is invalid and cannot be removed." error when decrypting (Client Side).

Any help would be greatly appreciated!

Thanks.

Schalk
  • 123
  • 1
  • 8
  • Check this: https://stackoverflow.com/questions/8583112/padding-is-invalid-and-cannot-be-removed – Sunil Nov 27 '17 at 08:56
  • `networkStream.Read(bytesFrom, 0, (int)client.ReceiveBufferSize);` - may not be your problem but you shouldn't ignore the return value from this function - it may be less than the number of bytes you asked for. – Dylan Nicholson Nov 27 '17 at 09:07
  • @DylanNicholson I've reverted back to hard-coding the size to 64 bytes, as the encrypted values are ALWAYS 64 bytes long. I've fixed the issue on the client side, but now the issue popped up server side. I think the problem might be a result of this: `byte[] cipherText = new byte[bytesToDecrypt.Length - IV.Length]; Array.Copy(bytesToDecrypt, IV, IV.Length); Array.Copy(bytesToDecrypt, IV.Length, cipherText, 0, cipherText.Length);` since this line of code changes the length of the array from 64 to 48 bytes (the Init Vector is 16 bytes long) – Schalk Nov 27 '17 at 09:25
  • @Sunil Unfortunately that link is not helpful in the slightest. I have seen this link before, but as I am already setting the padding explicitly that post really doesn't help at all. The IV is 16 bytes long, the salt/key is 32 bytes long, and the encrypted byte array is 64 bytes long. I'm sorry if I'm coming across as rude but if you read my post/went through my code you would see that that link would not be helpful. Thanks for the effort anyway. Edit: Also, you can see my keys are identical and that I am flushing the final blocks of the CryptoStream – Schalk Nov 27 '17 at 09:28
  • On your server side in the `Encrypt` method, you are assigning the result buffer before flushing the final block. But you have to assign it afterwards. – KBO Nov 27 '17 at 09:35
  • Well spotted KBO - you would definitely want to move the `encryptedBytes = ms.ToArray();` statement to after the flush. I'm still not sure what you mean about hard-coding the buffer size - my point was that the length of the buffer you pass to `Read( )` on a socket stream does not guarantee you that that many bytes will always be read (though when all network traffic is local, it's usually a pretty safe bet, so probably isn't your problem here). – Dylan Nicholson Nov 27 '17 at 10:47
  • @KBO Good spot. While I did move the code up, I'm now unfortunately getting the error server-side and not client-side. So I suppose it is a step in the right direction! – Schalk Nov 27 '17 at 10:52
  • @DylanNicholson I moved the line, which moved the error server-side and not client side! Which is a step in the right direction, but it's still breaking. I have tried rewriting the code several times, as well as copying-and-pasting encryption code that a coworker gave me, but I am constantly getting this error. Which would make me think that some data is being lost/corrupted while transporting - however the bytes server side and the bytes client side are identical. I am at my wits end here. – Schalk Nov 27 '17 at 10:55
  • Read about posting a [mcve]. When the question is about encryption, why should we read a ton of Socket code? – H H Nov 27 '17 at 12:24

1 Answers1

0

This following code snipped is from a working project. I recommend to create a (unit) test or console project first. So you can test your encryption/decryption without overhead.

Data helper class:

public class CryptData
{
  private byte[]               _buffer;
  private System.Text.Encoding _textEncoding;
  private int                  _numPaddingBytes;

  public static readonly System.Text.Encoding DefaultTextEncoding = System.Text.Encoding.GetEncoding("Windows-1252");

  public CryptData()
  {
    _textEncoding    = DefaultTextEncoding;
    _buffer          = null;
    _numPaddingBytes = 0;
  }

  public CryptData(byte[] buffer)
  {
    _textEncoding    = DefaultTextEncoding;
    _buffer          = buffer;
    _numPaddingBytes = 0;
  }

  public CryptData(System.Text.Encoding textEncoding)
  {
    if (textEncoding == null)
      throw new ArgumentNullException("textEncoding");

    _textEncoding    = textEncoding;
    _buffer          = null;
    _numPaddingBytes = 0;
  }

  public CryptData(System.Text.Encoding textEncoding, string text)
  {
    if (textEncoding == null)
      throw new ArgumentNullException("textEncoding");

    _textEncoding    = textEncoding;
    this.Text        = text;
    _numPaddingBytes = 0;
  }

  public CryptData(string text) : this(DefaultTextEncoding, text)
  {
  }

  public bool IsEmpty
  {
    get { return (_buffer == null || _buffer.Length < 1); }
  }

  public byte[] Buffer
  {
    get { return _buffer; }
    set { _buffer = value; }
  }

  public int BufferLength
  {
    get { return _buffer != null ? _buffer.Length : 0; }
  }

  public int NumPaddingBytes
  {
    get { return _numPaddingBytes; }
    set { _numPaddingBytes = value; }
  }

  public System.Text.Encoding TextEncoding
  {
    get { return _textEncoding; }
    set
    {
      if (value == null)
        throw new ArgumentNullException("TextEncoding");

      _textEncoding = value;
    }
  }

  public string Text
  {
    get
    {
      return (_buffer != null ? _textEncoding.GetString(_buffer) : null);
    }
    set
    {
      _buffer = ( value != null ? _textEncoding.GetBytes(value) : null);
    }
  }

  public string Base64Text
  {
    get
    {
      return (_buffer != null ? Convert.ToBase64String(_buffer) : null);
    }
    set 
    { 
      _buffer = (value != null ? Convert.FromBase64String(value) : null);
    }
  }
}

AES wrapper class:

/// <summary>
/// This class wraps the AES encryption algorithm (RijndaelManaged class) and can be used to encrypt and decrypt data.
/// The passphrases hash value is used to set the key and initialization vector of the algorithm. Internally, SHA384
/// is used to create a 192 bits key and a 128 bits initialization vector.
/// </summary>
public class SymmetricEncryptionHelper : IDisposable
{
  private RijndaelManaged _algorithm = null;
  private byte[]          _iv = null; // initialization vector
  private byte[]          _key = null; // key
  private string          _passPhrase = string.Empty;
  private int             _streamBufferLength = 2048;
  private PaddingMode     _padding;

  /// <summary>
  /// Creates a SymmetricEncryptionHelper object.
  /// </summary>
  /// <param name="passPhrase">The passphrase.</param>
  public SymmetricEncryptionHelper(string passPhrase)
    : this(passPhrase, PaddingMode.PKCS7)
  {
  }

  /// <summary>
  /// Creates a SymmetricEncryptionHelper object.
  /// </summary>
  /// <param name="passPhrase">The passphrase.</param>
  /// <param name="padding">The padding mode to use.</param>
  public SymmetricEncryptionHelper(string passPhrase, PaddingMode padding)
  {
    this.PassPhrase = passPhrase;
    _padding        = padding;
  }

  /// <summary>
  /// Sets the required passphrase
  /// </summary>
  public string PassPhrase
  {
    set
    {
      if (value == null)
        throw new ArgumentNullException("PassPhrase");
      if (value.Length < 1)
        throw new ArgumentException("PassPhrase.Length < 1", "PassPhrase");

      _passPhrase = value;
      InitializeKeys();
      _algorithm = null; // reset algorithm, because the passphrase has changed
    }
  }

  /// <summary>
  /// Gets or sets the internal buffer length used for encryption/decryption if streams are used.
  /// Range [16...4096].
  /// </summary>
  public int StreamBufferLength
  {
    get { return _streamBufferLength; }
    set
    {
      if (value < 16)
        throw new ArgumentOutOfRangeException("StreamBufferLength", value, "StreamBufferLength < 16");
      if (value > 4096)
        throw new ArgumentOutOfRangeException("StreamBufferLength", value, "StreamBufferLength > 4096");

      _streamBufferLength = value;
    }
  }

  /// <summary>
  /// Creates
  /// </summary>
  /// <param name="data"></param>
  /// <returns></returns>
  private CryptData CreateSHA384Hash(CryptData data)
  {
    CryptData hash = new CryptData();

    using (var algorithm = new SHA384Managed())
    {
      hash.Buffer = algorithm.ComputeHash(data.Buffer);
    }

    return hash;
  }

  /// <summary>
  /// Initializes the key and initialization vector using the passphrases hash value.
  /// </summary>
  protected virtual void InitializeKeys()
  {
    // create a 48 byte hash value used to initialize the initialization vector and the key
    CryptData hashValue = CreateSHA384Hash(new CryptData(_passPhrase));

    // create the key and initialization vector
    this._key = new byte[24]; // 192 bits
    this._iv = new byte[16]; // 128 bits

    // copy the results
    Array.Copy(hashValue.Buffer, _key, _key.Length);
    Array.Copy(hashValue.Buffer, _key.Length, _iv, 0, _iv.Length);
  }

  /// <summary>
  /// Initializes the internal RijndaelManaged algorithm, assigns the key and
  /// initialization vector. If the object already exists, nothing is done.
  /// </summary>
  protected virtual void InitializeAlgorithm()
  {
    if (_algorithm == null)
    {
      _algorithm         = new RijndaelManaged();
      _algorithm.Key     = _key;
      _algorithm.IV      = _iv;
      _algorithm.Padding = _padding;
    }
  }

  /// <summary>
  /// Encrypts the given data.
  /// </summary>
  /// <param name="data">The data to encrypt.</param>
  /// <returns>Returns the encrypted data.</returns>
  public CryptData Encrypt(CryptData data)
  {
    if (data == null)
      throw new ArgumentNullException("data");
    if (data.Buffer == null)
      throw new ArgumentNullException("data.Buffer");
    if (data.BufferLength < 1)
      throw new ArgumentException("data.BufferLength < 1", "data.Buffer");

    ICryptoTransform transform = null;
    MemoryStream memStream = null;
    CryptoStream cryptoStream = null;
    CryptData resultData = null;

    try
    {
      InitializeAlgorithm();
      transform = _algorithm.CreateEncryptor();
      memStream = new MemoryStream();
      cryptoStream = new CryptoStream(memStream, transform, CryptoStreamMode.Write);
      cryptoStream.Write(data.Buffer, 0, data.BufferLength);
      cryptoStream.FlushFinalBlock();

      resultData = new CryptData(memStream.ToArray());
      resultData.NumPaddingBytes = resultData.BufferLength - data.BufferLength;
    }
    catch (Exception ex)
    {
      Debug.WriteLine("SymmetricEncryptionHelper.Encrypt exception: " + ex);
      throw;
    }
    finally
    {
      if (transform != null)
        transform.Dispose();
      if (memStream != null)
        memStream.Close();
      if (cryptoStream != null)
        cryptoStream.Dispose();
    }

    return resultData;
  }

  /// <summary>
  /// Encrypts the given data.
  /// </summary>
  /// <param name="stream">The stream to encrypt.</param>
  /// <returns>Returns the encrypted data.</returns>
  public CryptData Encrypt(System.IO.Stream stream)
  {
    if (stream == null)
      throw new ArgumentNullException("stream");
    if (stream.Length < 1)
      throw new ArgumentException("stream.Length < 1", "stream");

    ICryptoTransform transform = null;
    MemoryStream memStream = null;
    CryptoStream cryptoStream = null;
    CryptData resultData = null;
    byte[] buffer;
    int writtenBytes;

    try
    {
      InitializeAlgorithm();
      transform = _algorithm.CreateEncryptor();
      memStream = new MemoryStream();
      cryptoStream = new CryptoStream(memStream, transform, CryptoStreamMode.Write);

      buffer = new byte[_streamBufferLength];
      stream.Position = 0;
      while (0 < (writtenBytes = stream.Read(buffer, 0, buffer.Length)))
      {
        cryptoStream.Write(buffer, 0, writtenBytes);
      }
      cryptoStream.FlushFinalBlock();

      resultData = new CryptData(memStream.ToArray());
      resultData.NumPaddingBytes = resultData.BufferLength - (int)stream.Length;
    }
    catch (Exception ex)
    {
      Debug.WriteLine("SymmetricEncryptionHelper.Encrypt exception: " + ex);
      throw;
    }
    finally
    {
      if (transform != null)
        transform.Dispose();
      if (memStream != null)
        memStream.Close();
      if (cryptoStream != null)
        cryptoStream.Dispose();
    }

    return resultData;
  }

  /// <summary>
  /// Decrypts the given data.
  /// </summary>
  /// <param name="encryptedData">The encrypted data.</param>
  /// <returns>Returns the decrypted data.</returns>
  public CryptData Decrypt(CryptData encryptedData)
  {
    if (encryptedData == null)
      throw new ArgumentNullException("encryptedData");
    if (encryptedData.Buffer == null)
      throw new ArgumentNullException("encryptedData.Buffer");
    if (encryptedData.BufferLength < 1)
      throw new ArgumentException("encryptedData.BufferLength < 1", "encryptedData.Buffer");

    ICryptoTransform transform = null;
    MemoryStream memStream = null;
    CryptoStream cryptoStream = null;
    CryptData resultData = null;
    byte[] decryptedBuffer;

    try
    {
      InitializeAlgorithm();
      transform = _algorithm.CreateDecryptor();
      memStream = new MemoryStream(encryptedData.Buffer);
      cryptoStream = new CryptoStream(memStream, transform, CryptoStreamMode.Read);

      // create result buffer and read the data from the crypto stream (do decryption)
      decryptedBuffer = new byte[encryptedData.BufferLength];
      cryptoStream.Read(decryptedBuffer, 0, decryptedBuffer.Length);

      // create the result data
      if (encryptedData.NumPaddingBytes > 0)
      { // remove padded bytes if neccessary
        byte[] decryptedBufferUnpadded = new byte[decryptedBuffer.Length - encryptedData.NumPaddingBytes];
        Array.Copy(decryptedBuffer, decryptedBufferUnpadded, decryptedBufferUnpadded.Length);
        resultData = new CryptData(decryptedBufferUnpadded);
      }
      else
        resultData = new CryptData(decryptedBuffer);
    }
    catch (Exception ex)
    {
      Debug.WriteLine("SymmetricEncryptionHelper.Decrypt exception: " + ex);
      throw;
    }
    finally
    {
      if (transform != null)
        transform.Dispose();
      if (memStream != null)
        memStream.Close();
      if (cryptoStream != null)
        cryptoStream.Dispose();
    }

    return resultData;
  }

  /// <summary>
  /// Decrypts the given data.
  /// </summary>
  /// <param name="encryptedStream">The encrypted stream.</param>
  /// <returns>Returns the decrypted data.</returns>
  public CryptData Decrypt(System.IO.Stream encryptedStream)
  {
    if (encryptedStream == null)
      throw new ArgumentNullException("encryptedStream");
    if (encryptedStream.Length < 1)
      throw new ArgumentException("encryptedStream.Length < 1", "encryptedStream");

    ICryptoTransform transform = null;
    MemoryStream memStream = null;
    CryptoStream cryptoStream = null;
    CryptData resultData = null;
    byte[] decryptedBuffer;
    int readBytes;

    try
    {
      InitializeAlgorithm();
      transform = _algorithm.CreateDecryptor();
      memStream = new MemoryStream(_streamBufferLength);
      cryptoStream = new CryptoStream(encryptedStream, transform, CryptoStreamMode.Read);

      // create result buffer and read the data from the crypto stream (do decryption)
      decryptedBuffer = new byte[_streamBufferLength];
      while (0 < (readBytes = cryptoStream.Read(decryptedBuffer, 0, decryptedBuffer.Length)))
      {
        memStream.Write(decryptedBuffer, 0, readBytes); // store decrypted bytes
      }

      // create the result data
      resultData = new CryptData(memStream.ToArray());
    }
    catch (Exception ex)
    {
      Debug.WriteLine("SymmetricEncryptionHelper.Decrypt exception: " + ex);
      throw;
    }
    finally
    {
      if (transform != null)
        transform.Dispose();
      if (memStream != null)
        memStream.Close();
      if (cryptoStream != null)
        cryptoStream.Dispose();
    }

    return resultData;
  }

  /// <summary>
  /// Disposes the object.
  /// </summary>
  public void Dispose()
  {
    try
    {
      if (_algorithm != null)
        _algorithm.Clear();
    }
    catch (Exception ex)
    {
      Debug.WriteLine("SymmetricEncryptionHelper.Dispose exception: " + ex);
    }
  }
}

Console test class:

  class Program
  {
    static void Main(string[] args)
    {
      Console.WriteLine("AES Test Program\n\n");

      string passPhrase = "MyPassword";
      string secretText = "This is my secret text";

      var encrypted = Encrypt(passPhrase, new CryptData(secretText));

      Console.WriteLine("Encrypted: " + encrypted.Base64Text);

      var decrypted = Decrypt(passPhrase, encrypted);

      Console.WriteLine("Decrypted: " + decrypted.Text);

      Console.WriteLine("\nPress <ENTER> to exit");
      Console.ReadLine();
    }

    private static CryptData Encrypt(string passPhrase, CryptData plainData)
    {
      using (var enc = new SymmetricEncryptionHelper(passPhrase))
      {
        return enc.Encrypt(plainData);
      }
    }

    private static CryptData Decrypt(string passPhrase, CryptData encryptedData)
    {
      using (var dec = new SymmetricEncryptionHelper(passPhrase))
      {
        return dec.Decrypt(encryptedData);
      }
    }
  }
KBO
  • 653
  • 7
  • 17