using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace EncryptionTest
{
    class Program
    {

        // Main method.
        public static void Main()
        {
            Console.Write("Are you Encrypting or Decrypting (E or D)?");
            string choice = Console.ReadLine();
            if (choice.ToLower().Trim()[0] == 'e')
            {
                // Create a new DES key.
                DESCryptoServiceProvider key = new DESCryptoServiceProvider();

                // Get some plain text from the User
                Console.WriteLine("Enter a String to Crypt:");
                string plainTextOrigional = Console.ReadLine();

                // Encrypt a string to a byte array.
                byte[] encryptedTextBuffer = Encrypt(plainTextOrigional, key);

                // Print the encrypted text in Base64
                Console.WriteLine("Here is the Encrypted Text (in Base64):");
                Console.WriteLine(Convert.ToBase64String(encryptedTextBuffer));

                // Print the Key
                Console.Write("Here is the Key (in Base64): ");
                Console.WriteLine(Convert.ToBase64String(key.Key));
                Console.Write("Here is the Initialazation Vector (in Base64): ");
                Console.WriteLine(Convert.ToBase64String(key.IV));
            }
            else
            {
                // Create a new DES key.
                DESCryptoServiceProvider key = new DESCryptoServiceProvider();

                //Ask the user for the Encrypted Text in BAse64
                Console.WriteLine("Enter a Base64 String to Decrypt:");
                byte[] dataToDecrypt = Convert.FromBase64String(Console.ReadLine());

                //Ask the user for the Key
                Console.Write("Enter the Base64 encoded Key:");
                key.Key = Convert.FromBase64String(Console.ReadLine());
 
                //Ask the use for the Initialization Vector
                Console.Write("Enter the Base64 encoded Initialazation Vector:");
                key.IV = Convert.FromBase64String(Console.ReadLine());


                // Decrypt the byte array back to a string.
                string decryptedText = Decrypt(dataToDecrypt, key);

                // Display the plaintext value to the console.
                Console.WriteLine("Here is you decrypted Text:");
                Console.WriteLine(decryptedText);
            }
        }
        
	    // Encrypt the string.
        public static byte[] Encrypt(string PlainText, SymmetricAlgorithm key)
        {
            // Create a memory stream.
            MemoryStream ms = new MemoryStream();

            // Create a CryptoStream using the memory stream and the 
            // CSP DES key.  
            CryptoStream encStream = new CryptoStream(ms, key.CreateEncryptor(), CryptoStreamMode.Write);

            // Create a StreamWriter to write a string
            // to the stream.
            StreamWriter sw = new StreamWriter(encStream);

            // Write the plaintext to the stream.
            sw.WriteLine(PlainText);

            // Close the StreamWriter and CryptoStream.
            sw.Close();
            encStream.Close();

            // Get an array of bytes that represents
            // the memory stream.
            byte[] buffer = ms.ToArray();

            // Close the memory stream.
            ms.Close();

            // Return the encrypted byte array.
            return buffer;
        }

       // Decrypt the byte array.
        public static string Decrypt(byte[] CypherText, SymmetricAlgorithm key)
        {
            // Create a memory stream to the passed buffer.
            MemoryStream ms = new MemoryStream(CypherText);

            // Create a CryptoStream using the memory stream and the 
            // CSP DES key. 
            CryptoStream encStream = new CryptoStream(ms, key.CreateDecryptor(), CryptoStreamMode.Read);

            // Create a StreamReader for reading the stream.
            StreamReader sr = new StreamReader(encStream);

            // Read the stream as a string.
            string val = sr.ReadLine();

            // Close the streams.
            sr.Close();
            encStream.Close();
            ms.Close();
                
            return val;
        }
    }
}