Solved

C#  - How to encrypt a data dictionary

Posted on 2013-06-24
5
801 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
  • 3
  • 2
5 Comments
 
LVL 42

Expert Comment

by:sedgwick
Comment Utility
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
Comment Utility
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
Comment Utility
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 500 total points
Comment Utility
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
Comment Utility
Thanks
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Article by: Ivo
Anonymous Types in C# by Ivo Stoykov Anonymous Types are useful when  we do not need to follow usual work-flow -- creating object of some type, assign some read-only values and then doing something with them. Instead we can encapsulate this read…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

772 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now