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;
        }
    }
}