Solved

C#  - How to encrypt a data dictionary

Posted on 2013-06-24
5
848 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
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 500 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

ScreenConnect 6.0 Free Trial

Discover new time-saving features in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

Question has a verified solution.

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

Introduction This article series is supposed to shed some light on the use of IDisposable and objects that inherit from it. In essence, a more apt title for this article would be: using (IDisposable) {}. I’m just not sure how many people would ge…
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
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

778 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