?
Solved

C#  - How to encrypt a data dictionary

Posted on 2013-06-24
5
Medium Priority
?
952 Views
Last Modified: 2013-06-25
I have a class that read a delimited file with a string and a integer and store it into a data dictionary.

I will like to encrypt it into a file and later be able to read the encrypt file and put data back into the data dictioanry.  

I have the code below and not sure where I need to add to encrypt the data.  
I thought I will write data dictionary into a memory file and then write using cryptostream. Is that correct?  If I do this how can I retrieve it and restore the key/value into the data dictionary
0
Comment
Question by:tommym121
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 42

Expert Comment

by:sedgwick
ID: 39273713
A simple way would be convert the dictionary to string by having 2 different delimiters inside.
One between key and its value and another between each key-value pair.
Example:
key1@value1|key2@value2|key3@value3

To convert dictionary to such representation:
String.Join("|", dictionary.Select(kv=>String.Format("{0}@{1}",kv.Key,kv.Value).ToArray());
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 39273716
U must choose delimiters that u know are not part of the dictionary keys or values otherwise u wont get the conversion right.
Next step is to encrypt the string.
To get dictionary back from the string:
var dictionary = str.Split('|').ToDictionary(s=>s.Split('@')[0],s=>s.Split('@')[1]);
0
 

Author Comment

by:tommym121
ID: 39274312
I have created the encrypt file with the routine below. How would I read it back.
Do I first read all the bytes from CryptoStream. Then put into the memorystream, then read from memory stream and restore data into the dictionary.  Any help will appreciated

        public void EncryptAndSerialize(string filename, SymmetricAlgorithm key)
        {
            using (FileStream fs = File.Open(filename, FileMode.Create))
            {
                using (CryptoStream cs = new CryptoStream(fs, key.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        foreach (var item in map)
                        {

                            string line = item.Key + "," + item.Value + "\n";
                            byte[] array = Encoding.ASCII.GetBytes(line);
                            ms.Write(array, 0, line.Length);
                        }
                        byte[] allbytes = ms.GetBuffer();
                        cs.Write(allbytes, 0, allbytes.Length);
                    }

                }
            }
        }
0
 
LVL 42

Accepted Solution

by:
sedgwick earned 2000 total points
ID: 39274389
here's full and tested code to encrypt dictionary and save it to file, and decrypt dictionary data from file and restore dictionary:
        static void Main(string[] args)
        {
//create dictionary for testing
            IDictionary<string, string> map = new Dictionary<string, string>();
            map.Add("lebron", "james");
            map.Add("1234", "1234");
            map.Add("SymmetricAlgorithm key", "SymmetricAlgorithm key");

//create the algorithm to be used in the encryption
            var algo = SymmetricAlgorithm.Create();

//encrypt dictionary to file using the encryption algorithm 
            EncryptToFile(@"c:\temp\test.dat", algo, map);

//decrypt file and restore dictionary
            map = DecryptFromFile(@"c:\temp\test.dat", algo);
        }

        public static void EncryptToFile(string filename, SymmetricAlgorithm key, IDictionary<string, string> map)
        {
            var str = String.Join("|", map.Select(kv => String.Format("{0}@{1}", kv.Key, kv.Value)).ToArray());

            using (FileStream fs = File.Open(filename, FileMode.Create))
            {
                var bytes = EncryptStringToBytes(str, key.Key, key.IV);
                fs.Write(bytes, 0, bytes.Length);
            }
        }

        public static IDictionary<string, string> DecryptFromFile(string filename, SymmetricAlgorithm key)
        {
            byte[] bytes = new byte[1024];
            List<byte> data = new List<byte>();
            using (FileStream fs = File.Open(filename, FileMode.Open))
            {
                int read = 0;
                while ((read = fs.Read(bytes, 0, 1024)) > 0)
                {
                    data.AddRange(bytes.Take(read));
                }

                var str = DecryptStringFromBytes(data.ToArray(), key.Key, key.IV);
                IDictionary<string, string> map = str.Split('|').ToDictionary(s => s.Split('@')[0], s => s.Split('@')[1]);
                return map;
            }
        }

        static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
        {
            // Check arguments. 
            if (plainText == null || plainText.Length <= 0)
                throw new ArgumentNullException("plainText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("Key");
            byte[] encrypted;
            // Create an Rijndael object 
            // with the specified key and IV. 
            using (Rijndael rijAlg = Rijndael.Create())
            {
                rijAlg.Key = Key;
                rijAlg.IV = IV;

                // Create a decrytor to perform the stream transform.
                ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

                // Create the streams used for encryption. 
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {

                            //Write all data to the stream.
                            swEncrypt.Write(plainText);
                        }
                        encrypted = msEncrypt.ToArray();
                    }
                }
            }


            // Return the encrypted bytes from the memory stream. 
            return encrypted;

        }

        static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
        {
            // Check arguments. 
            if (cipherText == null || cipherText.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("Key");

            // Declare the string used to hold 
            // the decrypted text. 
            string plaintext = null;

            // Create an Rijndael object 
            // with the specified key and IV. 
            using (Rijndael rijAlg = Rijndael.Create())
            {
                rijAlg.Key = Key;
                rijAlg.IV = IV;

                // Create a decrytor to perform the stream transform.
                ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

                // Create the streams used for decryption. 
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {

                            // Read the decrypted bytes from the decrypting stream 
                            // and place them in a string.
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }

            }

            return plaintext;
        }
    }

Open in new window

0
 

Author Closing Comment

by:tommym121
ID: 39275985
Thanks
0

Featured Post

Enroll in August's Course of the Month

August's CompTIA IT Fundamentals course includes 19 hours of basic computer principle modules and prepares you for the certification exam. It's free for Premium Members, Team Accounts, and Qualified Experts!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article describes a simple method to resize a control at runtime.  It includes ready-to-use source code and a complete sample demonstration application.  We'll also talk about C# Extension Methods. Introduction In one of my applications…
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

741 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question