Click here to Skip to main content
15,886,812 members
Articles / Programming Languages / C#

Simple Cryptographer - Simple DES/AES Implementation in C#

Rate me:
Please Sign up or sign in to vote.
2.81/5 (29 votes)
21 May 2007CPOL4 min read 292.3K   10.8K   55  
It's very simple and does not focus on performance, but I think that it is simple.
using System;
using System.Collections.Generic;
using System.Text;

namespace SimpleCryptographer.DES
{
    class ProcessDES : CommonProcess
    {
        public ProcessDES(Form1.ProgressEventHandler IncrementProgress, Form1.ProgressInitHandler InitProgress)
        {
            this.IncrementProgress = IncrementProgress;
            this.InitProgress = InitProgress;
        }
        
        #region Event for progress bar
        public event Form1.ProgressInitHandler InitProgress;
        public event Form1.ProgressEventHandler IncrementProgress;

        protected virtual void OnIncrementProgress(ProgressEventArgs e)
        {
            if (IncrementProgress != null)
                IncrementProgress(this, e);
        }

        protected virtual void OnInitProgress(ProgressInitArgs e)
        {
            if (InitProgress != null)
                InitProgress(this, e);
        }
        #endregion

        #region Encryption Process
        public override/*static*/ string EncryptionStart(string text, string key, bool IsTextBinary)
        {
            #region Get 16 sub-keys using key
                        
            string hex_key = this.FromTextToHex(key);
            string binary_key = this.FromHexToBinary(hex_key);
            string key_plus = this.DoPermutation(binary_key, DESData.pc_1);

            string C0 = "", D0 = "";

            C0 = this.SetLeftHalvesKey(key_plus);
            D0 = this.SetRightHalvesKey(key_plus);

            Keys keys = this.SetAllKeys(C0, D0);

            #endregion

            #region Encrypt process

            //string hex_text = this.FromTextToHex(text);
            string binaryText = "";

            if (IsTextBinary == false)
            {
                binaryText = this.FromTextToBinary(text);
            }
            else
            {
                binaryText = text;
            }

            binaryText = this.setTextMutipleOf64Bits(binaryText);

            #region Initialize Progress Bar
            OnInitProgress(new ProgressInitArgs(binaryText.Length));
            #endregion

            StringBuilder EncryptedTextBuilder = new StringBuilder(binaryText.Length);

            for (int i = 0; i < (binaryText.Length / 64); i++)
            {
                string PermutatedText = this.DoPermutation(binaryText.Substring(i * 64, 64), DESData.ip);

                string L0 = "", R0 = "";

                L0 = this.SetLeftHalvesKey(PermutatedText);
                R0 = this.SetRightHalvesKey(PermutatedText);

                string FinalText = this.FinalEncription(L0, R0, keys, false);

                EncryptedTextBuilder.Append(FinalText);

                #region Increase Progress Bar
                OnIncrementProgress(new ProgressEventArgs(FinalText.Length));
                #endregion
            }

            return EncryptedTextBuilder.ToString();

            #endregion
        }
        #endregion

        #region Decryption Process 
        public override/*static*/ string DecryptionStart(string text, string key, bool IsTextBinary)
        {
            #region Get 16 sub-keys using key

            string hex_key = this.FromTextToHex(key);
            string binary_key = this.FromHexToBinary(hex_key);
            string key_plus = this.DoPermutation(binary_key, DESData.pc_1);

            string C0 = "", D0 = "";

            C0 = this.SetLeftHalvesKey(key_plus);
            D0 = this.SetRightHalvesKey(key_plus);

            Keys keys = this.SetAllKeys(C0, D0);

            #endregion

            #region Decrypt process

            string binaryText = "";

            if (IsTextBinary == false)
            {
                binaryText = this.FromTextToBinary(text);
            }
            else
            {
                binaryText = text;
            }

            binaryText = this.setTextMutipleOf64Bits(binaryText);

            #region Initialize Progress Bar
            OnInitProgress(new ProgressInitArgs(binaryText.Length));
            #endregion

            StringBuilder DecryptedTextBuilder = new StringBuilder(binaryText.Length);

            for (int i = 0; i < (binaryText.Length / 64); i++)
            {
                string PermutatedText = this.DoPermutation(binaryText.Substring(i * 64, 64), DESData.ip);

                string L0 = "", R0 = "";

                L0 = this.SetLeftHalvesKey(PermutatedText);
                R0 = this.SetRightHalvesKey(PermutatedText);

                string FinalText = this.FinalEncription(L0, R0, keys, true);

                #region It's for correct subtracted '0' that have added for set text multiple of 64bit
                if ((i * 64 + 64) == binaryText.Length)
                {
                    StringBuilder last_text = new StringBuilder(FinalText.TrimEnd('0'));

                    int count = FinalText.Length - last_text.Length;

                    if ((count % 8) != 0)
                    {
                        count = 8 - (count % 8);
                    }

                    string append_text = "";

                    for (int k = 0; k < count; k++)
                    {
                        append_text += "0";
                    }

                    DecryptedTextBuilder.Append(last_text.ToString() + append_text);
                }
                #endregion
                else
                {
                    DecryptedTextBuilder.Append(FinalText);
                }

                //DecryptedTextBuilder.Append(FinalText);

                #region Increase Progress Bar
                OnIncrementProgress(new ProgressEventArgs(FinalText.Length));
                #endregion
            }

            return DecryptedTextBuilder.ToString();//.TrimEnd('0');

            #endregion
        }
        #endregion
        
        #region Check a string whether Korean or not. - not used in this program.
        public /*static*/ bool IsKorean(char word)
        {
            if (word >= '\xAC00' && word <= '\xD7AF')
            {
                return true;
            }

            if (word >= '\x3130' && word <= '\x318F')
            {
                return true;
            }

            return false;
        }
        #endregion

        #region Transform a text to a hex
        public string FromTextToHex(string text)
        {
            string hexstring = "";

            foreach (char word in text)
            {
                hexstring += String.Format("{0:X}", Convert.ToInt32(word));
            }

            return hexstring;
        }
        #endregion

        #region Transform a hex or a binary number to text
        public string FromHexToText(string hexstring)
        {
            StringBuilder text = new StringBuilder(hexstring.Length / 2);

            for (int i = 0; i < (hexstring.Length / 2); i++)
            {
                string word = hexstring.Substring(i * 2, 2);
                text.Append((char)Convert.ToInt32(word, 16));
            }

            return text.ToString();
        }

        public /*static*/ string FromBinaryToText(string binarystring)        
        {
            StringBuilder text = new StringBuilder(binarystring.Length / 8);

            for (int i = 0; i < (binarystring.Length / 8); i++)
            {
                string word = binarystring.Substring(i * 8, 8);
                text.Append((char)Convert.ToInt32(word, 2));
                //text += (char)Convert.ToInt32(word, 16);
            }

            return text.ToString();
        }
        #endregion
        
        #region Set a length of text to multiple of 64 bits
        public string setTextMutipleOf64Bits(string text)
        {
            if ((text.Length % 64) != 0)
            {
                int maxLength = 0;
                maxLength = ((text.Length / 64) + 1) * 64;
                text = text.PadRight(maxLength, '0');
            }

            return text;
        }
        #endregion

        #region Transform an integer to binary number
        public string FromTextToBinary(string text)
        {
            StringBuilder binarystring = new StringBuilder(text.Length * 8);

            foreach (char word in text)
            {
                int binary = (int)word;
                int factor = 128;

                for (int i = 0; i < 8; i++)
                {
                    if (binary >= factor)
                    {
                        binary -= factor;
                        binarystring.Append("1");
                    }
                    else
                    {
                        binarystring.Append("0");
                    }
                    factor /= 2;
                }
            }

            return binarystring.ToString();
        }

        public static string FromDeciamlToBinary(int binary)
        {
            if (binary < 0)
            {
                Console.WriteLine("It requires a integer greater than 0.");
                return null;
            }

            string binarystring = "";
            int factor = 128;

            for (int i = 0; i < 8; i++)
            {
                if (binary >= factor)
                {
                    binary -= factor;
                    binarystring += "1";
                }
                else
                {
                    binarystring += "0";
                }
                factor /= 2;
            }

            return binarystring;
        }

        public static byte FromBinaryToByte(string binary)
        {
            byte value = 0;
            int factor = 128;

            for (int i = 0; i < 8; i++)
            {
                if (binary[i] == '1')
                {
                    value += (byte)factor;                    
                }

                factor /= 2;
            }

            return value;
        }
        #endregion

        #region Transform a hex integer to a binary number
        public string FromHexToBinary(string hexstring)
        {
            string binarystring = "";

            try
            {
                for (int i = 0; i < hexstring.Length; i++)
                {
                    int hex = Convert.ToInt32(hexstring[i].ToString(), 16);

                    int factor = 8;

                    for(int j=0; j<4; j++)
                    {
                        if (hex >= factor)
                        {
                            hex -= factor;
                            binarystring += "1";
                        }
                        else
                        {
                            binarystring += "0";
                        }
                        factor /= 2;
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message + " - wrong hexa integer format.");
            }

            return binarystring;
        }
        #endregion

        #region Permutation
        public string DoPermutation(string text, int[] order)
        {
            StringBuilder PermutatedText = new StringBuilder(order.Length);

            for (int i = 0; i < order.Length; i++)
            {
                PermutatedText.Append(text[order[i] - 1]);
            }

            return PermutatedText.ToString();
        }
        
        //For SBoxes Transformation
        public string DoPermutation(string text, int[,] order)
        {
            string PermutatedText = "";

            int rowIndex = Convert.ToInt32(text[0].ToString() + text[text.Length - 1].ToString(), 2);
            int colIndex = Convert.ToInt32(text.Substring(1, 4), 2);

            PermutatedText = ProcessDES.FromDeciamlToBinary(order[rowIndex, colIndex]);

            return PermutatedText;
        }        
        #endregion

        #region Divide a text to left and right halves
        public string SetLeftHalvesKey(string text)
        {
            return this.SetHalvesKey(true, text);
        }

        public string SetRightHalvesKey(string text)
        {
            return this.SetHalvesKey(false, text);       
        }

        public string SetHalvesKey(bool IsLeft, string text)
        {
            if ((text.Length % 8) != 0)
            {
                Console.WriteLine("The key is not multiple of 8bit.");
                return null;
            }

            int midindex = (text.Length / 2) - 1;

            string result = "";

            if (IsLeft)
            {
                result = text.Substring(0, midindex + 1);
            }
            else
            {
                result = text.Substring(midindex + 1);
            }

            return result;
        }
        #endregion

        #region Do Leftshift
        public string LeftShift(string text)
        {
            return this.LeftShift(text, 1);
        }

        public string LeftShift(string text, int count)
        {
            if (count < 1)
            {
                Console.WriteLine("The count of leftshift is must more than 1 time.");
                return null;
            }

            string temp = text.Substring(0, count);
            StringBuilder shifted = new StringBuilder(text.Length);
            shifted.Append(text.Substring(count) + temp);

            return shifted.ToString();
        }
        #endregion

        #region Key���� ���ϴ� �޼��� - Get all of keys
        public Keys SetAllKeys(string C0, string D0)
        {
            Keys keys = new Keys();
            keys.Cn[0] = C0;
            keys.Dn[0] = D0;

            for (int i = 1; i < keys.Cn.Length; i++)
            {
                keys.Cn[i] = this.LeftShift(keys.Cn[i - 1], DESData.nrOfShifts[i]);
                keys.Dn[i] = this.LeftShift(keys.Dn[i - 1], DESData.nrOfShifts[i]);
                keys.Kn[i - 1] = this.DoPermutation(keys.Cn[i] + keys.Dn[i], DESData.pc_2);
            }          

            return keys;
        }
        #endregion

        #region Do Encryption
        public string FinalEncription(string L0, string R0, Keys keys, bool IsReverse)
        {
            string Ln = "", Rn = "", Ln_1 = L0, Rn_1 = R0;

            int i = 0;

            if (IsReverse == true)
            {
                i = 15;
            }

            while (this.IsEnough(i, IsReverse))
            {
                Ln = Rn_1;
                Rn = this.XOR(Ln_1, this.f(Rn_1, keys.Kn[i]));

                //Next Step of L1, R1 is L2 = R1, R2 = L1 + f(R1, K2), hence, value of Step1's Ln, Rn is Rn_1, Ln_1 in Step2.
                Ln_1 = Ln;
                Rn_1 = Rn;

                if (IsReverse == false)
                {
                    i += 1;
                }
                else
                {
                    i -= 1;
                }
            }

            string R16L16 = Rn + Ln;

            string Encripted_Text = this.DoPermutation(R16L16, DESData.ip_1);

            return Encripted_Text;
        }

        public /*static*/ bool IsEnough(int i, bool IsReverse)
        {
            return (IsReverse == false) ? i < 16 : i >= 0;            
        }
        #endregion

        #region The function f
        public string f(string Rn_1, string Kn)
        {
            string E_Rn_1 = this.E_Selection(Rn_1);

            string XOR_Rn_1_Kn = this.XOR(E_Rn_1, Kn);

            string sBoxedText = this.sBox_Transform(XOR_Rn_1_Kn);

            string P_sBoxedText = this.P(sBoxedText);

            return P_sBoxedText;
        }
        #endregion

        #region The function P
        public string P(string text)
        {
            string PermutatedText = "";

            PermutatedText = this.DoPermutation(text, DESData.pc_p);

            return PermutatedText;
        }
        #endregion

        #region SBoxes transformation
        public string sBox_Transform(string text)
        {
            StringBuilder TransformedText = new StringBuilder(32);

            for (int i = 0; i < 8; i++)
            {
                string temp = text.Substring(i * 6, 6);
                TransformedText.Append(this.DoPermutation(temp, DESData.sBoxes[i]));
            }

            return TransformedText.ToString();
        }
        #endregion
         
        #region E Selection
        public string E_Selection(string Rn_1)
        {
            string ExpandedText = this.DoPermutation(Rn_1, DESData.pc_e);

            return ExpandedText;
        }
        #endregion

        #region XOR operation
        public string XOR(string text1, string text2)
        {
            if (text1.Length != text2.Length)
            {
                Console.WriteLine("Two data blocks for XOR are must get same size.");
                return null;
            }

            StringBuilder XORed_Text = new StringBuilder(text1.Length);

            for (int i = 0; i < text1.Length; i++)
            {
                if (text1[i] != text2[i])
                {
                    XORed_Text.Append("1");
                }
                else
                {
                    XORed_Text.Append("0");
                }
            }

            return XORed_Text.ToString();
        }
        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Korea (Republic of) Korea (Republic of)
I'm a super-elementary programmer.
I live in Suwon, Republic of Korea.
And i'm not very good at English.
hahaha!!!

Comments and Discussions