2

I am sending Data from a Server to a Client over the Internet using WCF web services in form of Data Objects. I have created a Class, which is Serializable, and using this class to send my data.

Below is an example of my class:

[Serializable]
public class DBOList
{
    public string A{ get; set; }
    public string B { get; set; }
}

Is it possible for me to Encrypt the data in this object, and send it to the client as a stream?

If not What is the best approach to achive this?

Encryption Code:

        DBOList NewLst = new DBOList();
        NewLst.A = "Value 1";
        NewLst.B = "Value 2";

        byte[] key = { 1, 2, 3, 4, 5, 6, 7, 8 };
        byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 };

        DESCryptoServiceProvider des = new DESCryptoServiceProvider();

        // Encryption
        using (var fs = new MemoryStream())
        {
            var cryptoStream = new CryptoStream(fs, des.CreateEncryptor(key, iv), CryptoStreamMode.Write);
            BinaryFormatter formatter = new BinaryFormatter();

            // This is where you serialize the class
            formatter.Serialize(cryptoStream, NewLst);
            cryptoStream.FlushFinalBlock();
        }
Kush
  • 245
  • 1
  • 3
  • 11

2 Answers2

2

It is best to use SSL instead, which will add all the security you need, while avoiding most pitfalls.

Short of that, you can of course use a CryptoStream. You can only encrypt bytes, but you already indicated that you understand this by mentioning Serializable.

Note that if you want to create your own secure stream you will need:

  • two securely generated keys, and encryption and a MAC key
  • a secure cipher such as AesManaged
  • set using (the defaults) CBC and PKCS7Padding
  • retrieve the randomly generated IV and prepend it to the ciphertext
  • create a HMACSHA256 over the result

to be reasonably safe. If this does not ring any bells, use the most up to date TLS implementation.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Thanks for the feedback. Reason i cant take SSL route is because not all our clients will want to Purchase SSL certificates. I have tried CryptoStream but getting stuck at the point of Decryption And Deserialization. Let me add the Encyrption code to the Original Question – Kush Aug 11 '12 at 11:41
  • 1
    You can create your own certificates and distribute them, you don't need a (commercial) root CA. You need to exchange keys anyway if you don't use SSL. – Maarten Bodewes Aug 11 '12 at 11:45
  • Thanks, i think ill use my own Certificates. But For the purpose of learning, please explain how to achieve the encryption and decryption. It may come handy one day. Thanx once again – Kush Aug 11 '12 at 11:55
  • 1
    SSL is not (always) a substitute for message encryption. – H H Aug 11 '12 at 13:06
  • @HenkHolterman You are absolutely right, but in most cases with client/server communication it is. Even if it isn't it would take a lot of stings out of the message encryption - e.g. the issue with padding oracles/message integrity. – Maarten Bodewes Aug 11 '12 at 13:26
  • @user1559231 I was trying to look up a nice C# example on how to use CBC mode encryption and HMAC together but I got out with zip, nothing, nada, except [this](http://stackoverflow.com/questions/5235161/aes256-cbc-hmac-sha256-ensuring-confidentiality-and-authentication) telling you that you should use TLS. Small wonder. Try the .NET variant of Bouncy Castle with AES-GCM mode encryption instead if you really want to create something secure. – Maarten Bodewes Aug 11 '12 at 13:48
0

AES encryption and decryption an class object in C#

This is the best way for AES encryption and decryption an class object in C#. Here i'm explain about AES Key and AES IV usage. And provide an example to write and read byte[] into filestream using AES encryption and decryption an class object in C#.

  1. Create new class
    public class Profile
    {
        [JsonPropertyName("name")]
        [JsonProperty(PropertyName = "name")]
        internal string Name { get; set; }

        [JsonPropertyName("password")]
        [JsonProperty(PropertyName = "password")]
        internal string Password { get; set; }

        [JsonPropertyName("profileData")]
        [JsonProperty(PropertyName = "profileData")]
        public byte[] ProfileData { get; set; }
    }
  1. AES KEY used the secret key for the symmetric algorithm. This is secret key, is something you keep secret. Anyone who knows your key (or can guess it) can decrypt any data you've encrypted with it (or forge any authentication codes you've calculated with it, etc.).

  2. AES IV used as initialization vector (IV) for the symmetric algorithm. Initialization vector is, in its broadest sense, just the initial value used to start some iterated process. So you can maintain in your code itself.

        private readonly static byte[] Key = Convert.FromBase64String("AsISxq9OwdZag1163OJqwovXfSWG98m+sPjVwJecfe4=");

        private readonly static byte[] IV = Convert.FromBase64String("Aq0UThtJhjbuyWXtmZs1rw==");
  1. Example for write and read byte[] into filestream using AES encryption and decryption an class object in C#.
class Program
    {
        private readonly static byte[] Key = Convert.FromBase64String("AsISxq9OwdZag1163OJqwovXfSWG98m+sPjVwJecfe4=");

        private readonly static byte[] IV = Convert.FromBase64String("Aq0UThtJhjbuyWXtmZs1rw==");

        public static Profile Profile { get; set; }

        static void Main(string[] args)
        {
            Profile = new Profile();
            string fileName = "D:\\Profile.txt";
            Profile.Name = "Ramesh";
            Profile.Password = "Password";
            Console.WriteLine("Enter your option:");
            Console.WriteLine("1. Encryption");
            Console.WriteLine("2. Decryption");
            string option = Console.ReadLine();

            if (option == "1")
            {
                FileStream fsWrite = new FileStream(fileName, FileMode.Create, FileAccess.Write);
                string serializeProfile = Newtonsoft.Json.JsonConvert.SerializeObject(Profile);
                Profile.ProfileData = EncryptStringToBytes(serializeProfile);
                fsWrite.Write(Profile.ProfileData, 0, Profile.ProfileData.Length);
                fsWrite.Close();
            }
            else
            {
                FileStream fsRead = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                BinaryReader br = new BinaryReader(fsRead);
                long numBytes = new FileInfo(fileName).Length;
                string decryptedText = DecryptStringFromBytes(br.ReadBytes((int)numBytes));
                Profile DeserializeProfile = Newtonsoft.Json.JsonConvert.DeserializeObject<Profile>(decryptedText);
                Console.WriteLine("Name :" + DeserializeProfile.Name);
                Console.WriteLine("Password :" + DeserializeProfile.Password);
                Console.ReadKey();
                fsRead.Close();
            }
        }

        private static byte[] EncryptStringToBytes(string profileText)
        {
            byte[] encryptedAuditTrail;

            using (Aes newAes = Aes.Create())
            {
                newAes.Key = Key;
                newAes.IV = IV;

                ICryptoTransform encryptor = newAes.CreateEncryptor(Key, IV);

                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            swEncrypt.Write(profileText);
                        }
                        encryptedAuditTrail = msEncrypt.ToArray();
                    }
                }
            }

            return encryptedAuditTrail;
        }

        private static string DecryptStringFromBytes(byte[] profileText)
        {
            string decryptText;

            using (Aes newAes = Aes.Create())
            {
                newAes.Key = Key;
                newAes.IV = IV;

                ICryptoTransform decryptor = newAes.CreateDecryptor(Key, IV);

                using (MemoryStream msDecrypt = new MemoryStream(profileText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            decryptText = srDecrypt.ReadToEnd();
                        }
                    }
                }
            }


            return decryptText;
        }
    }
  1. Console output snap

Console Output snap

  1. GitHub link : https://strramesh.github.io/EncryptionAndDecryption/
Ramesh
  • 1
  • 1