[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 707
  • Last Modified:

Trouble With Text File Encryption (C#)

I have asked a few questions regarding encryption so far and I am just not grasping the concept. I want to take data that my application generates in string form, and encrypt it, then write it to a text file. I think want to programmatically be able to retrieve the data, subsequently decrypting it. If someone could write me an example (no links to other examples please) so I can better grasp this concept I would greatly apprecaite it. An easy example would be to simply encrypt the string value "test" and write that to a file. Then have another method that reads the file, decrypts it and displays the word "test" back in a messagebox. Also, I want my keys to be static and hard coded into the app. Thanks!
0
Pretzel_Jesus
Asked:
Pretzel_Jesus
1 Solution
 
CoyotesITCommented:
Here is a sample taken from this KB article that should get you started in the right direction.

http://support.microsoft.com/kb/307010
using System;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Text;
 
namespace CSEncryptDecrypt
{
   class Class1
   {
      //  Call this function to remove the key from memory after use for security
      [System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint="RtlZeroMemory")]
      public static extern bool ZeroMemory(IntPtr Destination, int Length);
		
      // Function to Generate a 64 bits Key.
      static string GenerateKey() 
      {
         // Create an instance of Symetric Algorithm. Key and IV is generated automatically.
         DESCryptoServiceProvider desCrypto =(DESCryptoServiceProvider)DESCryptoServiceProvider.Create();
 
         // Use the Automatically generated key for Encryption. 
         return ASCIIEncoding.ASCII.GetString(desCrypto.Key);
      }
 
      static void EncryptFile(string sInputFilename,
         string sOutputFilename, 
         string sKey) 
      {
         FileStream fsInput = new FileStream(sInputFilename, 
            FileMode.Open, 
            FileAccess.Read);
 
         FileStream fsEncrypted = new FileStream(sOutputFilename, 
            FileMode.Create, 
            FileAccess.Write);
         DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
         DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
         DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
         ICryptoTransform desencrypt = DES.CreateEncryptor();
         CryptoStream cryptostream = new CryptoStream(fsEncrypted, 
            desencrypt, 
            CryptoStreamMode.Write); 
 
         byte[] bytearrayinput = new byte[fsInput.Length];
         fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
         cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
         cryptostream.Close();
         fsInput.Close();
         fsEncrypted.Close();
      }
 
      static void DecryptFile(string sInputFilename, 
         string sOutputFilename,
         string sKey)
      {
         DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
         //A 64 bit key and IV is required for this provider.
         //Set secret key For DES algorithm.
         DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
         //Set initialization vector.
         DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
 
         //Create a file stream to read the encrypted file back.
         FileStream fsread = new FileStream(sInputFilename, 
            FileMode.Open, 
            FileAccess.Read);
         //Create a DES decryptor from the DES instance.
         ICryptoTransform desdecrypt = DES.CreateDecryptor();
         //Create crypto stream set to read and do a 
         //DES decryption transform on incoming bytes.
         CryptoStream cryptostreamDecr = new CryptoStream(fsread, 
            desdecrypt,
            CryptoStreamMode.Read);
         //Print the contents of the decrypted file.
         StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);
         fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd());
         fsDecrypted.Flush();
         fsDecrypted.Close();
      } 
 
      static void Main()
      {
         // Must be 64 bits, 8 bytes.
         // Distribute this key to the user who will decrypt this file.
         string sSecretKey;
         
         // Get the Key for the file to Encrypt.
         sSecretKey = GenerateKey();
 
         // For additional security Pin the key.
         GCHandle gch = GCHandle.Alloc( sSecretKey,GCHandleType.Pinned );
         
         // Encrypt the file.        
         EncryptFile(@"C:\MyData.txt", 
            @"C:\Encrypted.txt", 
            sSecretKey);
 
         // Decrypt the file.
         DecryptFile(@"C:\Encrypted.txt", 
            @"C:\Decrypted.txt", 
            sSecretKey);
 
         // Remove the Key from memory. 
         ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2);
         gch.Free();
      }
   }
}

Open in new window

0
 
Pretzel_JesusAuthor Commented:
I have seen articles such as this one and I frankly do not understand them. Thats why I am looking for someone to provide me an example that caters to the specifications I had posted in the original question. That hopefully will give me better clarity so I can build it beyond that on my own.
0
 
keustermansCommented:
Here is a class that I wrote that I use to decrypt and encrypt  strings such as conection strings.

I am sure that you know how to read and write to a file.

you have the option to encrypt with a built in standard Encryption Key or you can pass an encryption key as a parameter in the constructor.

To use this class is easy:
string myString="Test Encryption";
string myEncryptedString;
Crypto crypto = new Crypto();
myEncryptedString=crypto.Encrypt(myString);
/// <summary>
    /// Summary description for CryptoBO
    /// </summary>
    public class Crypto
    {
        Byte[] Key, Vector;
        private ICryptoTransform EncryptorTransform,
           DecryptorTransform;
 
        private System.Text.UTF8Encoding UTF8Encoder;
 
        /// <summary>
        /// Initializes the simple AES class with an Encryption Key.
        /// Use this Constructor if the Encryption Key is going to be enterd by the user
        /// </summary>
        /// <param name="key">The encryption key.</param>
 
        public Crypto(string key)
        {
            UTF8Encoder = new UTF8Encoding();
            RijndaelManaged rm = new RijndaelManaged();
 
            if (rm.LegalKeySizes.Length > 0)
            {
                int lessSize = 0;
                int moreSize = rm.LegalKeySizes[0].MinSize;
                while (key.Length * 8 > moreSize)
                {
                    lessSize = moreSize;
                    moreSize += rm.LegalKeySizes[0].SkipSize;
                }
                Key = UTF8Encoder.GetBytes(key.PadRight(moreSize / 8, ' '));
                Vector = UTF8Encoder.GetBytes(key.PadRight(moreSize / 8, ' '));
            }
            EncryptorTransform = rm.CreateEncryptor(Key, Key);
            DecryptorTransform = rm.CreateDecryptor(Key, Key);
        }
        /// <summary>
        /// Initializes the simple AES class with an Encryption Key.
        /// Use this format is you are creating a key and vector in code with the
        /// GenerateEncryptionVector and GenerateEncryptionKey functions
        /// </summary>
        /// <param name="Key">Byte[]</param>
        /// <param name="Vector">Byte[]</param>
        public Crypto(Byte[] Key, Byte[] Vector)
        {
            this.Key = Key;
            this.Vector = Vector;
            //This is our encryption method
            RijndaelManaged rm = new RijndaelManaged();
            //Create an encryptor and a decryptor using our 
            //encryption method, key, and vector.
            EncryptorTransform = rm.CreateEncryptor(this.Key,
               this.Vector);
            DecryptorTransform = rm.CreateDecryptor(this.Key,
               this.Vector);
 
            //Used to translate bytes to text and vice versa
            UTF8Encoder = new System.Text.UTF8Encoding();
        }
 
        public Crypto()
        {
            byte[] defaultKey = { 198, 167, 93, 121, 252, 215, 8, 135, 4, 81, 227, 56, 117, 39, 72, 249 };
 
            this.Key = defaultKey;
            this.Vector = defaultKey;
 
            //This is our encryption method
            RijndaelManaged rm = new RijndaelManaged();
            //Create an encryptor and a decryptor using our 
            //encryption method, key, and vector.
            EncryptorTransform = rm.CreateEncryptor(this.Key,
               this.Vector);
            DecryptorTransform = rm.CreateDecryptor(this.Key,
               this.Vector);
 
            //Used to translate bytes to text and vice versa
            UTF8Encoder = new UTF8Encoding();
        }
        /// <summary>
        /// Generates an encryption key.
        /// </summary>
        /// <returns>byte[] encryption key. Store it some place    
        /// safe.</returns>
        static public byte[] GenerateEncryptionKey()
        {
            //Generate a Key.
            RijndaelManaged rm = new RijndaelManaged();
            rm.GenerateKey();
            return rm.Key;
        }
 
        /// <summary>
        /// Generates a unique encryption vector
        /// </summary>
        /// <returns>byte[] vector value</returns>
        static public byte[] GenerateEncryptionVector()
        {
            bool CorrectSize = false;
            //Generate a Vector
            RijndaelManaged rm = new RijndaelManaged();
            while (!CorrectSize)
            {
                rm.GenerateIV();
                if (rm.IV.Length == 16)
                    CorrectSize = true;
            }
            return rm.IV;
        }
 
        /// <summary>
        /// Encrypt some text and return an encrypted byte array.
        /// </summary>
        /// <param name="TextValue">The Text to encrypt</param>
        /// <returns>byte[] of the encrypted value</returns>
        public string Encrypt(string TextValue)
        {
            //Translates our text value into a byte array.
            Byte[] bytes = UTF8Encoder.GetBytes(TextValue);
 
            //Used to stream the data in and out of the CryptoStream.
            MemoryStream memoryStream = new MemoryStream();
 
            /*
             * We will have to write the unencrypted bytes to the 
             * stream, then read the encrypted result back from the 
             * stream.
             */
            #region Write the decrypted value to the encryption stream
            CryptoStream cs = new CryptoStream(memoryStream,
               EncryptorTransform, CryptoStreamMode.Write);
            cs.Write(bytes, 0, bytes.Length);
            cs.FlushFinalBlock();
            #endregion
 
            #region Read encrypted value back out of the stream
            memoryStream.Position = 0;
            byte[] encrypted = new byte[memoryStream.Length];
            memoryStream.Read(encrypted, 0, encrypted.Length);
            #endregion
 
            //Clean up.
            cs.Close();
            memoryStream.Close();
            return System.Convert.ToBase64String(encrypted, 0, encrypted.Length);
        }//END OF ENCRYPT
 
        public string Decrypt(string data)
        {
            byte[] EncryptedValue = System.Convert.FromBase64String(data);
            #region Write the encrypted value to the decryption stream
            MemoryStream encryptedStream = new MemoryStream();
            CryptoStream decryptStream = new
               CryptoStream(encryptedStream,
               DecryptorTransform, CryptoStreamMode.Write);
            decryptStream.Write(EncryptedValue, 0,
               EncryptedValue.Length);
            decryptStream.FlushFinalBlock();
            #endregion
 
            #region Read the decrypted value from the stream.
            encryptedStream.Position = 0;
            Byte[] decryptedBytes = new Byte[encryptedStream.Length];
 
            encryptedStream.Read(decryptedBytes, 0,
               decryptedBytes.Length);
            encryptedStream.Close();
            #endregion
 
            return UTF8Encoder.GetString(decryptedBytes);
        }//END OF DECRYPT
    }//END OF CLASS

Open in new window

0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now