Improve company productivity with a Business Account.Sign Up

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

C# - How to encrypt a data dictionary

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
tommym121
Asked:
tommym121
  • 3
  • 2
1 Solution
 
Meir RivkinFull stack Software EngineerCommented:
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
 
Meir RivkinFull stack Software EngineerCommented:
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
 
tommym121Author Commented:
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
 
Meir RivkinFull stack Software EngineerCommented:
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
 
tommym121Author Commented:
Thanks
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

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